2009-12-01 9 views
3

J'ai du code qui interroge Active Directory pour vérifier l'existence de l'utilisateur. J'essaie de vérifier une longue liste d'environ 1300 ids. J'ai essayé plusieurs méthodes pour vérifier si un compte d'utilisateur (LINQ à AD, DirectorySearcher (avec et sans un parentEntry) et aussi un DirectoryEntry qui lie au chemin WinNT: //). Chaque fois qu'il reviendra et dire que plusieurs utilisateurs n'existent pas. Si je code en dur leurs userids dans le code et exécute pour individuellement, il valide l'existence. Si j'essaie de le faire dans une boucle foreach, j'ai plusieurs faux négatifs.Active Directory ne trouve pas tous les utilisateurs en C#

Voici le code que je utilise en ce moment ..

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"}; 

List<string> nonExistingUsers = new List<string>(); 
List<string> ExistingUsers = new List<string>(); 
foreach (string s in userIDs) 
{ 
DirectorySearcher search = new DirectorySearcher(); 
search.Filter = String.Format("(SAMAccountName={0})", s); 
search.PropertiesToLoad.Add("cn"); 
DirectorySearcher ds = new DirectorySearcher(de, "(&(objectClass=user)(cn=" + s + "))", new string[] { "Name" }, SearchScope.Subtree); 
SearchResultCollection resultCollection = ds.FindAll(); 
SearchResult result = search.FindOne(); 
if (result != null) 
    ExistingUsers.Add(s); 
else 
    nonExistingUsers.Add(s); 
} 

Toutes les suggestions ou les raisons pour lesquelles je recevais les faux négatifs?

Répondre

4

Couple de choses:

  • d'abord

    tout, essayez d'utiliser la « anr = » (résolution de nom ambigu) dans votre filtre LDAP - il recherche plusieurs attributs liés nom et faciliter la recherche. Le UserID pourrait ne pas faire partie de la réelle « nom commun » (CN = user1)

  • d'autre part, utiliser le objectCategory au lieu de objectClass - le objectCategory est à valeur unique et indexé et donc un peu juste plus rapide sur les recherches

  • troisièmement: pourquoi appelez-vous d'abord .FindAll() puis .FindOne() sur la ligne suivante? Ne semble pas vraiment nécessaire du tout ....

  • WinNT: // est vraiment seulement pour la rétrocompatibilité et si vous avez besoin de traiter avec des comptes informatiques locaux - essayez de l'éviter autant que possible, il expose aussi beaucoup moins de propriétés que LDAP

Voici mon code, j'écrirait:

static string[] userIDs = new string[] "user1","user2","user3","user4","user5","user6","user7","user8"...,"user1300"}; 

DirectoryEntry searchRoot = new DirectoryEntry("LDAP://cn=Users,dc=YourComp,dc=com"); 

List<string> nonExistingUsers = new List<string>(); 
List<string> ExistingUsers = new List<string>(); 

foreach (string s in userIDs) 
{ 
    DirectorySearcher search = new DirectorySearcher(searchRoot); 

    search.SearchScope = SearchScope.Subtree; 
    search.Filter = string.Format("(&(objectCategory=person)(anr={0}))", s); 

    SearchResultCollection resultCollection = ds.FindAll(); 

    if(resultCollection != null && resultCollection.Count > 0) 
     ExistingUsers.Add(s); 
    else 
     nonExistingUsers.Add(s); 
} 

est-ce que le travail dans votre scénario ??

De plus, si vous utilisez .NET 3.5 ou plus, les choses se sont beaucoup plus facile - voir:

Managing Directory Security Principals in the .NET Framework 3.5