Запрос LDAP в C # для получения списка компьютеров - PullRequest
0 голосов
/ 16 декабря 2018

Я работаю с LDAP в моем проекте Windows Forms C #.

Я создал CheckListBox и начал создавать метод, который запрашивает Active Directory для всех моих компьютеров, это среда.

Метод таков:

public string ComputerList()
{
        DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");

        DirectorySearcher computerSercher = new DirectorySearcher(rootDSE);

        computerSercher.PageSize = 10000;
        computerSercher.Filter = "(&(objectClass=computer))";
}

У меня также есть, как я уже сказал, CheckListBox.

Что я хочу сделать - это получить результат для запроса и каждого обнаруженного компьютера.добавьте его в свойство Items для CheckListBox.

Но я даже не подхожу к результату.это не похоже на PowerShell, который дает вам список объектов ...

Спасибо

1 Ответ

0 голосов
/ 16 декабря 2018

Ты почти у цели.Несколько вещей:

  1. Установите размер страницы равным 1000. AD не будет выдавать вам больше 1000 за раз, поэтому, если вы установите для него значение, превышающее 1000, вы получите (если DirectorySearcher не вернет то, что считает полной страницей, он перестанет спрашивать)
  2. Добавьте атрибуты, которые вы хотите прочитать, в коллекцию PropertiesToLoad.Если вы ничего не добавите, это даст вам каждый атрибут со значением, представляющим собой набор ненужных данных, которые вы не будете использовать.Скорее всего, вы захотите увидеть только атрибут cn (Общее имя).
  3. Используйте FindAll() для получения результатов.Убедитесь, что вы включили это в оператор using для предотвращения утечек памяти (в документации сказано так).
  4. Когда вы смотрите на результаты, каждое свойство представляется в виде массива, независимо от того, находится оно в AD или нет,Так что вам нужно будет использовать [0] в большинстве случаев.Для справки в будущем (здесь не применимо): если свойство не задано в AD, его вообще не будет в коллекции Properties, поэтому для необязательных атрибутов вам придется использовать Properties.Contains(), чтобы проверить,он там первый.

Работая из того, что у вас есть, вот метод, который возвращает список имен компьютеров:

public IEnumerable<string> ComputerList()
{
    DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");

    DirectorySearcher computerSercher = new DirectorySearcher(rootDSE)
    {
        PageSize = 1000,
        Filter = "(&(objectClass=computer))"
    };
    computerSercher.PropertiesToLoad.Add("cn");

    using (var results = computerSercher.FindAll())
    {
        foreach (SearchResult result in results)
        {
            yield return (string) result.Properties["cn"][0];
        }
    }
}

Обновление: Вответьте на свои вопросы в своем комментарии:

  1. yield в основном говорит ему «добавить этот элемент в коллекцию, которая будет возвращена».В фоновом режиме происходит немного больше, о чем вы можете прочитать здесь .Но в самых простых сроках, это избавляет вас от необходимости создавать свой собственный список, добавлять элементы в этот список и возвращать список.
  2. Я изменил тип возвращаемого значения с string на IEnumerable<string>, потому что вы получаете несколькорезультаты вашего поиска, поэтому я предполагаю, что вы хотите вернуть все эти результаты.Этот метод даст вам список имен компьютеров, а не только одно имя компьютера.
  3. FindAll() возвращает SearchResultCollection.По какой-то причине я не знаю, объекты, возвращенные из SearchResultCollection в foreach, представлены как object.Поэтому вам нужно явно привести их к SearchResult, чтобы использовать их.
...