Как вывести пользователей из активного каталога? - PullRequest
2 голосов
/ 19 октября 2010

Я немного борюсь с моей простой консольной дамп-программой.Я подключаюсь к AD, используя

DirectoryEntry entry =
    new DirectoryEntry("LDAP://" + domain, username, password);

, и оттуда я рекурсивно перебираю всех дочерних элементов с помощью

foreach (DirectoryEntry child in entry.Children)
{
    Traverse(child);
}

Затем я начинаю получать данные мамбо-джамбо, пользователи выскакивают более одного раза и обнуляют объектытак что мне интересно, если я обращаюсь с AD, то это просто дескриптор, а не копия, поэтому он не загружается полностью, когда я начинаю обходить его?

Есть ли какие-либо советы / указатели относительно того, что делать?

1 Ответ

3 голосов
/ 19 октября 2010

Если вы можете, перейдите на .NET 3.5 и используйте новое пространство имен System.DirectoryServices.AccountManagement - гораздо проще в использовании.

См .: Управление принципами безопасности каталогов в .NET Framework 3.5

Также: вы должны понимать, что Active Directory - это не просто список пользователей и групп, это иерархическая система подразделений (организационных единиц), которые могут быть вложены друг в друга и могут содержать пользователей, группы, компьютеры и больше.

Так что именно вы хотите сделать ?? Получить пользователей для данного подразделения (например, «Продажи») ?? Или действительно получить всех пользователей из вашей AD ?? Вы понимаете, что это может занять довольно много времени, в зависимости от размера AD вашей компании .......

Если вы действительно хотите получить ВСЕХ пользователей и ВСЕХ групп из всей вашей AD - вам, вероятно, следует установить DirectorySearcher на корневом уровне:

// set search root
DirectoryEntry deRoot = new DirectoryEntry("LDAP://dc=YourCompany,dc=com");

// declare directory searcher
DirectorySearcher dsUsers = new DirectorySearcher(deRoot);

// scope is full subtree, filter defines to search for users
dsUsers.SearchScope = SearchScope.SubTree;
dsUsers.Filter = "(objectCategory=person)";

// define what properties you want to have loaded into your search results
dsUsers.PropertiesToLoad.Add("givenName");
dsUsers.PropertiesToLoad.Add("surname");
dsUsers.PropertiesToLoad.Add("samAccountName");

// loop through results of search
foreach(SearchResult result in dsUsers.FindAll())
{
   if(result.Properties["givenName"] != null)
      string givenName = result.Properties["givenName"][0].ToString();

   if(result.Properties["surname"] != null)
      string surname = result.Properties["surname"][0].ToString();

   if(result.Properties["sAMAccountName"] != null)
      string samAccountName = result.Properties["sAMAccountName"][0].ToString();
}

При считывании свойств вашего SearchResult вам нужно проверить, чтобы убедиться, что вы действительно вернули значение - иначе ваше назначение потерпит крах и сгорит ....

Для групп просто используйте этот фильтр:

dsUsers.Filter = "(objectCategory=group)";

Если вы можете сузить область поиска, например, для данной OU вы можете получить гораздо лучшую производительность, поскольку дерево поиска становится меньше и, следовательно, поиск будет намного быстрее. Для этого просто укажите другой путь LDAP для вашей записи каталога deRoot (например, LDAP://OU=Sales,DC=YourCOmpany,DC=com или любой другой OU, в котором вы хотите искать).

Обновление: , как я уже сказал - с .NET 3.5 все становится намного проще! Вам нужно добавить ссылку на System.DirectoryServices.AccountManagement, а затем вы можете использовать что-то вроде этого, используя своего рода подход «запрос за примером»:

// create a domain context for the current domain
PrincipalContext domain = new PrincipalContext(ContextType.Domain);

// create a principal object decsribing what to search for
UserPrincipal user = new UserPrincipal(domain);
user.IsActive = true;

// create a principal searcher for running a search operation
PrincipalSearcher searcher = new PrincipalSearcher(user);

// run the query
PrincipalSearchResult<Principal> results = searcher.FindAll();

// iterate over all results
foreach (Principal result in results)
{
    Console.WriteLine("name: {0}", result.Name);
}

А для поиска групп просто создайте экземпляр GroupPrincipal, задайте для него любые свойства и затем передайте его в PrincipalSearcher для поиска групп.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...