2010-07-07 41 views
6

Estoy tratando de obtener una lista de usuarios y algunas propiedades sobre el usuario dentro de un grupo de directorio activo.Lista de usuarios en el grupo de distribución de Active Directory específico

Actualización:

Éstos son los dos métodos que tengo actualmente:

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 

La primera pieza funciona, aunque parece bastante ineficiente. Mi uso de memoria sube y sube a medida que se ejecuta y recibí el error this, aunque parece que se puede arreglar. El segundo método:

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 

El recuento de resultados parece variar de cada ejecución de la aplicación que me parece impar. No estoy seguro de si esta es una forma confiable de recuperar a los usuarios o si necesito modificar algo en mi búsqueda.

Respuesta

14

si se puede, no actualizar a .NET 3.5 y utilizar el nuevo mucho espacio de nombres mejorado System.DirectoryServices.AccountManagement. La gran introducción para esas nuevas clases se encuentra en Managing Directory Security Principals in the .NET Framework 3.5.

Con esto, su trabajo se vuelve trivial:

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

funciona eso para usted?

Si no puede usar .NET 3.5, debe inspeccionar la propiedad member del grupo. Los miembros del grupo son no almacenados como niños lógicamente debajo del grupo en la jerarquía, por lo que no puede encontrarlos usando 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 
} 

Véase el Quick List of C# Code Examples para Active Directory (o el mismo para Visual Basic .NET) en la biblioteca MSDN para este fragmento y más.

Actualización: si necesita los usuarios que pertenecen a un grupo en particular (ya que desea actualizar sus propiedades o algo así), que podría revertir el enfoque: búsqueda de todos los usuarios que tienen un memberOf propiedad equivalente a DN del grupo:

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

Looping a través de las propiedades de los miembros me acercó. De todas formas, necesitaré extraer propiedades del objeto miembro (nombre, correo electrónico, etc.). Supongo que tendré que convertir el groupmemberDN en su ejemplo a un tipo de objeto específico para que pueda extraer propiedades de él. –

+0

Gracias por su ayuda hasta ahora. Tengo dos preguntas. En primer lugar, usted había dicho que no podía obtener los miembros mediante el uso de un buscador de directorios, por lo que en su ejemplo actualizado veo que puedo, así que esperaba que pudiera dar más detalles sobre lo que quería decir allí. En segundo lugar, puedo obtener un resultado utilizando el buscador del directorio, pero el conteo de la colección parece variar cada vez que ejecuto mi aplicación, cuando debería ser consistente (actualmente no se está agregando a nadie al grupo). –

+0

@ Ek0nomik: ** no puedes ** enumerar un grupo para encontrar todos sus miembros, ya que un grupo es ** no ** un contenedor en AD sobre el que puedes enumerar. No contiene sus miembros como objetos secundarios. Sin embargo, puede enumerar una rama de directorio y encontrar todos los usuarios que son miembros de un grupo específico. –

2

Ámbito su búsqueda más amplia, donde los miembros pueden ser:

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

filtro basado en la pertenencia al grupo:

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

Probablemente necesite establecer directorySearcher.PageSize = 1000 si está ampliando el alcance. – decompiled

+0

Todavía no hubo suerte. Tomé exactamente lo que di, incluí mis valores específicos, pero no obtuve ningún resultado. –

+0

@ Ek0nomik - Mi respuesta original tenía un error tipográfico. Creo que "memberOf" no tiene espacio. – Greg

Cuestiones relacionadas