2009-02-04 13 views
19

J'ai le code qui recherche pour tous les utilisateurs dans un département:Obtenir la liste des utilisateurs de Active Directory dans un groupe donné AD

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(); 

Qu'est-ce que le filtre doit ressembler si je ne voulais tout le monde dans le " Manager Read Only "Groupe AD?

Est-ce que je vais tout à fait faux?

Répondre

34

En regardant votre recherche, j'ai quelques points pour vous. Tout d'abord, la recherche utilise objectClass (non indexé) au lieu de objectCategory (indexé). Énorme problème de performance avec cette requête. Vous voulez toujours plus de combiner les deux ensemble en fonction de ce que vous essayez de récupérer:

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

En ce qui concerne la recherche les utilisateurs dans un groupe, vous pouvez énumérer la liste des objets membres du groupe spécifique. Dans l'attribut de membre de l'objet de groupe est le distinguishedName de chaque utilisateur.

This article describes enumerating members of a group...

Ne pas oublier que vous devez gérer les groupes imbriqués du groupe parent, car il n'y a pas un moyen par défaut pour gérer cela avec les requêtes LDAP. Pour cela, vous devrez peut-être évaluer si l'objet membre est un groupe, puis obtenir l'attribut de membre pour ce groupe enfant. Enfin, vous devriez avoir l'habitude de spécifier un préfixe dns à votre requête.

Sans préfixe DNS:

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

Avec le préfixe DNS (tous les trois de travail):

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 seul domaine ne sera pas vous causer problème beaucoup mais quand vous essayez d'exécuter une recherche dans un environnement à plusieurs domaines, vous serez mordu sans cet ajout. J'espère que cela vous aidera à vous rapprocher de votre objectif.

+0

C'était une réponse très réfléchie. – wcm

+0

Ajouter (objectCategory = person) a vraiment accéléré la recherche. Merci beaucoup. – wcm

+0

Mauvais. Dans l'attribut de membre de l'objet de groupe est le distinguishedName de chaque utilisateur, OU UN AUTRE ** GROUPE ** NOM ... –

10

J'ai toujours trouvé Howto: (Almost) Everything In Active Directory via C# aide pour la plupart des questions AD.

+2

C'est un article très complet, mais je ne trouve pas celui-ci en particulier. Cela ne veut pas dire que ce n'est pas là, juste que je ne pouvais pas le voir. Je jongle avec une douzaine de choses en ce moment ... – wcm

+0

Ce lien est cassé. Je pense que c'est ce qui devrait être utilisé maintenant http://www.codeproject.com/Articles/90142/Tout-tout-en-Active-Directory-via-C-NET-Using – Ju66ernaut

+0

Aussi http://www.codeproject.com/ Articles/18102/Howto-Presque-Tout-Dans-Active-Directory-via-C – nzpcmad

6

Si vous connaissez déjà le chemin AD vers le groupe, il sera probablement plus facile d'ouvrir un DirectoryEntry sur celui-ci, puis de faire un DirectorySearcher à partir de là.

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

Il y a aussi un drapeau sur le Searcher pour savoir s'il faut explorer les sous-conteneurs, j'ai oublié le nom de la main.

+0

Ce serait pour le groupe FooBar AD? (Désolé je suis un peu nouveau à ce genre de choses) – wcm

+0

Oui.Tout dans AD a un nom distinctif (son chemin) http://msdn.microsoft.com/en-us/library/aa366101(VS.85).aspx –

3

J'utilise le code suivant (de 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) cela fonctionne très 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(); 
      } 
     } 
    } 
} 
Questions connexes