2010-07-07 4 views
6

Я пытаюсь получить список пользователей и некоторые свойства о пользователе из активной группы каталогов.Список пользователей в определенной группе распространения Active Directory

Update:

Вот два метода, которые я в настоящее время имеют:

Dim adGroup As New DirectoryEntry("LDAP://CN=MyGroup,OU=Groups,OU=Accounts,OU=All,DC=domain,DC=com") 
    Dim adMembers As Object 
    Dim objUser As ActiveDirectoryUser 
    Dim objUserList As New List(Of ActiveDirectoryUser) 
    Dim directoryEntry As DirectoryEntry 

    adMembers = adGroup.Invoke("Members", Nothing) 

    For Each adMember As Object In CType(adMembers, IEnumerable) 
     directoryEntry = New DirectoryEntry(adMember) 
     objUser = New ActiveDirectoryUser 

     objUser.UserId = directoryEntry.Properties.Item("sAMAccountName").Value.ToString() 
     objUser.Contract = directoryEntry.Properties.Item("ou").Value.ToString() 
     objUser.LastName = directoryEntry.Properties.Item("sn").Value.ToString() 
     objUser.FirstName = directoryEntry.Properties.Item("givenName").Value.ToString() 
     objUser.Email = directoryEntry.Properties.Item("mail").Value.ToString() 

     objUserList.Add(objUser) 
    Next 

Первая часть работы, хотя это кажется весьма неэффективным. Мое использование памяти поднимается и поднимается по мере его выполнения, и я получаю ошибку this, хотя похоже, что это можно исправить. Второй способ:

Dim results As SearchResultCollection 
    Dim directoryEntry2 As New DirectoryEntry("LDAP://DC=domain,DC=com") 
    Dim directorySearcher As New DirectorySearcher(directoryEntry2) 
    directorySearcher.PageSize = 1000 

    directorySearcher.Filter = "(&(objectCategory=person)" & _ 
          "(objectClass=user)" & _ 
          "(memberOf=CN=MyGroup,OU=Groups,OU=Accounts,OU=All,DC=domain,DC=com))" 


    directorySearcher.PropertiesToLoad.Add("ou") 
    directorySearcher.PropertiesToLoad.Add("sn") 
    directorySearcher.PropertiesToLoad.Add("givenName") 
    directorySearcher.PropertiesToLoad.Add("sAMAccountName") 
    directorySearcher.PropertiesToLoad.Add("mail") 

    results = directorySearcher.FindAll 

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

ответ

14

Если вы можете, не перейти на .NET 3.5 и использовать новый много улучшенное пространство имен System.DirectoryServices.AccountManagement. Отличное введение для этих новых классов находится в Managing Directory Security Principals in the .NET Framework 3.5.

С этим, ваша работа становится тривиальной:

PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN"); 
GroupPrincipal group = GroupPrincipal.FindByIdentity(ctx, "MyGroup"); 
PrincipalSearchResult<Principal> members = group.GetMembers(); 

ли эту работу для вас?

Если вы не можете использовать .NET 3.5, вы должны проверить свойство member группы. Члены группы: , а не, хранятся как дети логически под группой в иерархии, поэтому вы не можете найти их с помощью DirectorySearcher.

DirectoryEntry group = new DirectoryEntry("LDAP://CN=MyGroup,OU=Groups,OU=All,DC=Domain,DC=com"); 

foreach(object groupMemberDN in group.Properties["member"]) 
{ 
    // grab the group member's DN 
} 

Смотрите Quick List of C# Code Examples для Active Directory (или же для Visual Basic .NET) в библиотеке MSDN для этого фрагмента кода и многого другого.

Update: если вам нужен пользователей, принадлежащих к определенной группе (так как вы хотите, чтобы обновить свои свойства или что-то), вы можете полностью изменить подход: поиск всех пользователей, которые имеют memberOf свойство, эквивалентные DN группы:

DirectoryEntry root = new DirectoryEntry("LDAP://dc=domain,dc=com"); 
DirectorySearcher searcher = new DirectorySearcher(root); 

searcher.Filter = "(&(objectCategory=user)(memberOf=CN=MyGroup,OU=Groups,OU=All,DC=Domain,DC=com))"; 
// set other properties on the searcher 

foreach(object result in searcher.FindAll()) 
{ 
    // do whatever you need to do with the entry 
} 
+0

Пересечение свойств элемента меня близко. Мне все равно придется вытаскивать свойства из объекта-члена (имя, адрес электронной почты и т. Д.). Я предполагаю, что мне нужно указать groupmemberDN в вашем примере на определенный тип объекта, чтобы я мог извлекать из него свойства? –

+0

Спасибо за вашу помощь. У меня есть два вопроса. Во-первых, вы сказали, что я не могу получить участников, используя поисковик каталогов, поэтому в вашем обновленном примере я вижу, что могу, поэтому я надеялся, что вы сможете подробно рассказать о том, что вы имели в виду. Во-вторых, я могу получить результат, используя поисковик каталогов, но количество в коллекции, похоже, меняется каждый раз, когда я запускаю свое приложение, когда оно должно быть последовательным (в настоящее время никто не добавляется в группу). –

+0

@ Ek0nomik: вы ** не можете ** перечислить группу, чтобы найти все ее элементы, так как группа ** не ** контейнер в AD, который вы можете перечислить. Он не содержит своих членов как дочерние объекты. Однако вы можете перечислить ветку каталога и найти всех пользователей, входящих в определенную группу. –

2

Область поиска шире, где бы члены могут быть:

Dim directoryEntry As New DirectoryEntry("LDAP://OU=All,DC=Domain,DC=com") 

фильтр на основе членства в группе:

directorySearcher.Filter = "(&(objectCategory=person)" & _ 
          "(objectClass=user)" & _ 
          "(memberOf=CN=MyGroup,OU=Groups,OU=All,DC=Domain,DC=com))" 
+0

Возможно, вам потребуется установить directorySearcher.PageSize = 1000, если вы расширяете область действия. – decompiled

+0

Еще не повезло. Я взял именно то, что вы дали, сбросил мои конкретные значения, но я не получаю никаких результатов. –

+0

@ Ek0nomik - В моем первоначальном ответе была опечатка. Я думаю, что «memberOf» не имеет места. – Greg

Смежные вопросы