web-dev-qa-db-fra.com

Comment puis-je obtenir une liste d'utilisateurs à partir d'Active Directory?

Comment puis-je obtenir une liste d'utilisateurs à partir d'Active Directory? Est-il possible d'extraire un nom d'utilisateur, un prénom, un nom de famille? J'ai vu un message similaire où cela a été utilisé:

 PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "YOURDOMAIN");

Je n'ai jamais rien fait avec Active Directory, donc je suis complètement perdu. Toute aide serait grandement appréciée!

98
Mike

Si vous êtes nouveau sur Active Directory, je vous suggère de comprendre comment Active Directory stocke les données en premier.

Active Directory est en fait un serveur LDAP. Les objets stockés sur le serveur LDAP sont stockés de manière hiérarchique. C'est très similaire à vous stockez vos fichiers dans votre système de fichiers. C'est pourquoi il a reçu le nom Directory serveur et Active Directory

Les conteneurs et les objets sur Active Directory peuvent être spécifiés par un distinguished name. Le nom distingué est comme ceci CN=SomeName,CN=SomeDirectory,DC=yourdomain,DC=com. Comme une base de données relationnelle traditionnelle, vous pouvez exécuter une requête sur un serveur LDAP. C'est ce qu'on appelle une requête LDAP.

Il existe plusieurs façons d’exécuter une requête LDAP dans .NET. Vous pouvez utiliser DirectorySearcher à partir de System.DirectoryServices ou SearchRequest de System.DirectoryServices.Protocol.

Pour votre question, puisque vous demandez de trouver spécifiquement l'objet principal utilisateur, je pense que le moyen le plus intuitif consiste à utiliser PrincipalSearcher de System.DirectoryServices.AccountManagement. Vous pouvez facilement trouver beaucoup d'exemples différents à partir de Google. Voici un exemple qui fait exactement ce que vous demandez.

using (var context = new PrincipalContext(ContextType.Domain, "yourdomain.com"))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (var result in searcher.FindAll())
        {
            DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
            Console.WriteLine("First Name: " + de.Properties["givenName"].Value);
            Console.WriteLine("Last Name : " + de.Properties["sn"].Value);
            Console.WriteLine("SAM account name   : " + de.Properties["samAccountName"].Value);
            Console.WriteLine("User principal name: " + de.Properties["userPrincipalName"].Value);
            Console.WriteLine();
        }
    }
}
Console.ReadLine();

Notez que sur l'objet utilisateur AD, il existe un certain nombre d'attributs. En particulier, givenName vous donnera le First Name et sn vous donneront le Last Name. À propos du nom d'utilisateur. Je pense que vous vouliez dire le nom de connexion de l'utilisateur. Notez qu'il existe deux noms de connexion sur l'objet utilisateur AD. L'un d'entre eux est samAccountName, également appelé nom de connexion utilisateur antérieur à Windows 2000. userPrincipalName est généralement utilisé après Windows 2000.

211
Harvey Kwok

Si vous voulez filtrer les comptes actifs, ajoutez ceci au code de Harvey:

 UserPrincipal userPrin = new UserPrincipal(context);
 userPrin.Enabled = true;

après la première utilisation. Puis ajouter

  searcher.QueryFilter = userPrin;

avant de trouver tout. Et cela devrait vous amener les actifs.

21
apereira

Le mérite revient certainement à @Harvey Kwok, mais je voulais simplement ajouter cet exemple car, dans mon cas, je souhaitais obtenir une liste réelle de UserPrincipals. Il est probablement plus efficace de filtrer cette requête dès le départ, mais dans mon petit environnement, il est simplement plus facile de tout extraire, puis de filtrer au besoin plus tard dans ma liste.

Selon vos besoins, il se peut que vous n’ayez pas besoin de transtyper vers DirectoryEntry, mais certaines propriétés ne sont pas disponibles à partir de UserPrincipal.

using (var searcher = new PrincipalSearcher(new UserPrincipal(new PrincipalContext(ContextType.Domain, Environment.UserDomainName))))
{
    List<UserPrincipal> users = searcher.FindAll().Select(u => (UserPrincipal)u).ToList();
    foreach(var u in users)
        {
            DirectoryEntry d = (DirectoryEntry)u.GetUnderlyingObject();
            Console.WriteLine(d.Properties["GivenName"]?.Value?.ToString() + d.Properties["sn"]?.Value?.ToString());
        }
}
5
Jordan

Incluez le System.DirectoryServices.dll, puis utilisez le code ci-dessous:

DirectoryEntry directoryEntry = new DirectoryEntry("WinNT://" + Environment.MachineName);
string userNames="Users: ";

foreach (DirectoryEntry child in directoryEntry.Children)
{
    if (child.SchemaClassName == "User")
    {
        userNames += child.Name + Environment.NewLine   ;         
    }

}
MessageBox.Show(userNames);
1
FreeAsInBeer