2009-02-04 18 views
19

tengo código que busca para todos los usuarios en un departamento:obtener la lista de usuarios de Active Directory en un grupo de anuncios determinado

string Department = "Billing"; 
DirectorySearcher LdapSearcher = new DirectorySearcher(); 
LdapSearcher.PropertiesToLoad.Add("displayName"); 
LdapSearcher.PropertiesToLoad.Add("cn"); 
LdapSearcher.PropertiesToLoad.Add("department"); 
LdapSearcher.PropertiesToLoad.Add("title"); 
LdapSearcher.PropertiesToLoad.Add("memberOf"); 
LdapSearcher.Filter = string.Format("(&(objectClass=user)(department={0}))", Department); 
SearchResultCollection src = LdapSearcher.FindAll(); 

¿Cuál sería el filtro necesita para parecerse a si sólo quería que todos en el " Administrador de solo lectura "AD Group?

¿Estoy hablando de algo así?

Respuesta

34

En cuanto a su búsqueda, tengo un par de puntos para usted. Primero, la búsqueda usa objectClass (no indexado) en lugar de objectCategory (indexado). Enorme problema de rendimiento con esa consulta. Se podría casi siempre querer combinar los dos juntos en función de lo que está tratando de recuperar:

(&(objectCategory=person)(objectClass=user)) = All users (no contacts) 
(&(objectCategory=person)(objectClass=contact)) = All contacts (no users) 
(&(objectCategory=person)) = All users and contacts 

Como para buscar los usuarios de un grupo se puede enumerar la lista de objetos miembro del grupo específico. En el atributo de miembro del objeto de grupo es el distinguishedName de cada usuario.

This article describes enumerating members of a group...

no se olvide de que puede que tenga que manejar grupos anidados del grupo principal, ya que no hay una forma predeterminada para manejar esto con consultas LDAP. Para eso puede que necesite evaluar si el objeto miembro es un grupo y luego obtener el atributo de miembro para ese grupo de niños.

Por último, debe tener el hábito de especificar un prefijo dns para su consulta.

Sin prefijo DNS:

LDAP://ou=ouname,dc=domain,dc=com 

Con prefijo DNS (los tres trabajos):

LDAP://servername/ou=ouname,dc=domain,dc=com 
LDAP://servername.domain.com/ou=ouname,dc=domain,dc=com 
LDAP://domain.com/ou=ouname,dc=domain,dc=com 

un único dominio no le causará mucho problema, pero cuando tratas de ejecutar una búsqueda en un entorno de dominio múltiple le picarán sin esta adición. Espero que esto te ayude a acercarte más a tu objetivo.

+0

Esa fue una respuesta muy reflexiva. – wcm

+0

Agregar (objectCategory = persona) realmente hizo la búsqueda notablemente más rápida. Muchas gracias. – wcm

+0

Incorrecto. En el atributo de miembro del objeto de grupo se encuentra el distinguishedName de cada usuario, O OTRO ** NOMBRE ** DE GRUPO ... –

10

Siempre he encontrado Howto: (Almost) Everything In Active Directory via C# ayuda para la mayoría de las preguntas sobre AD.

+2

Este es un artículo muy completo, pero no encontré éste en concreto. Eso no quiere decir que no esté allí, solo que no pude verlo. Estoy haciendo malabares con una docena de cosas en este momento ... – wcm

+0

Este enlace está roto. Creo que esto es lo que debería usarse ahora http://www.codeproject.com/Articles/90142/Everything-in-Active-Directory-via-C-NET-Using – Ju66ernaut

+0

También http://www.codeproject.com/ Artículos/18102/Howto-Casi-todo-en-Active-Directory-via-C – nzpcmad

6

Si ya conoces la ruta AD del grupo, probablemente sea más fácil abrir un DirectoryEntry en ese punto, luego haz un DirectorySearcher desde allí.

using (DirectoryEntry de = new DirectoryEntry("LDAP://somedomain/CN=FooBar")) 
{ 
    DirectorySearcher search = new DirectorySearcher(de, ("(objectClass=user)")); 
} 

También hay una bandera en el Buscador de si se debe profundizar para recipientes auxiliares, no recuerdo el nombre de la mano.

+0

¿Eso sería para el AD Group FooBar? (Lo siento, soy un poco nuevo en esto) – wcm

+0

Sí.Todo en AD tiene un Nombre Distinguido (su ruta) http://msdn.microsoft.com/en-us/library/aa366101(VS.85).aspx –

3

Utilizo el siguiente código (desde http://blogs.technet.com/b/brad_rutkowski/archive/2008/04/15/c-getting-members-of-a-group-the-easy-way-with-net-3-5-discussion-groups-nested-recursive-security-groups-etc.aspx) funciona bien.

IList<string> getMembers(string domainName, string groupName) 
    { 
     PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName); 
     GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName); 

     if (grp == null) { 
      throw new ApplicationException("We did not find that group in that domain, perhaps the group resides in a different domain?"); 
     } 

     IList<string> members = new List<String>(); 

     foreach (Principal p in grp.GetMembers(true)) 
     { 
      members.Add(p.Name); //You can add more attributes, samaccountname, UPN, DN, object type, etc... 
     } 
     grp.Dispose(); 
     ctx.Dispose(); 

     return members; 
    } 
0
//Search for Group and list group members 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.DirectoryServices.AccountManagement; 

namespace ExportActiveDirectoryGroupsUsers 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      if (args == null) 
      { 
       Console.WriteLine("args is null, useage: ExportActiveDirectoryGroupsUsers OutputPath"); // Check for null array 
      } 
      else 
      { 
       Console.Write("args length is "); 
       Console.WriteLine(args.Length); // Write array length 
       for (int i = 0; i < args.Length; i++) // Loop through array 
       { 
        string argument = args[i]; 
        Console.Write("args index "); 
        Console.Write(i); // Write index 
        Console.Write(" is ["); 
        Console.Write(argument); // Write string 
        Console.WriteLine("]"); 
       } 
       try 
       { 
        using (var ServerContext = new PrincipalContext(ContextType.Domain, ServerAddress, Username, Password)) 
        { 
         /// define a "query-by-example" principal - here, we search for a GroupPrincipal 
         GroupPrincipal qbeGroup = new GroupPrincipal(ServerContext, args[0]); 

         // create your principal searcher passing in the QBE principal  
         PrincipalSearcher srch = new PrincipalSearcher(qbeGroup); 

         // find all matches 
         foreach (var found in srch.FindAll()) 
         { 
          GroupPrincipal foundGroup = found as GroupPrincipal; 

          if (foundGroup != null) 
          { 
           // iterate over members 
           foreach (Principal p in foundGroup.GetMembers()) 
           { 
            Console.WriteLine("{0}|{1}", foundGroup.Name, p.DisplayName); 
            // do whatever you need to do to those members 
           } 
          } 

         } 
        } 
        //Console.WriteLine("end"); 
       } 
       catch (Exception ex) 
       { 
        Console.WriteLine("Something wrong happened in the AD Query module: " + ex.ToString()); 
       } 
       Console.ReadLine(); 
      } 
     } 
    } 
} 
Cuestiones relacionadas