2009-10-22 19 views

Odpowiedz

23

Jeśli masz bardzo duży domenę, czy domena ma swoje granice skonfigurowane, w jaki sposób wiele przedmiotów można zwrócić na jedno wyszukiwanie, być może trzeba użyć stronicowania.

using System.DirectoryServices; //add to references 

public static List<string> GetComputers() 
{ 
    List<string> ComputerNames = new List<string>(); 

    DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no"); 
    DirectorySearcher mySearcher = new DirectorySearcher(entry); 
    mySearcher.Filter = ("(objectClass=computer)"); 
    mySearcher.SizeLimit = int.MaxValue; 
    mySearcher.PageSize = int.MaxValue; 

    foreach(SearchResult resEnt in mySearcher.FindAll()) 
    { 
     //"CN=SGSVG007DC" 
     string ComputerName = resEnt.GetDirectoryEntry().Name; 
     if (ComputerName.StartsWith("CN=")) 
      ComputerName = ComputerName.Remove(0,"CN=".Length); 
     ComputerNames.Add(ComputerName); 
    } 

    mySearcher.Dispose(); 
    entry.Dispose(); 

    return ComputerNames; 
} 
1

Zapytanie LDAP takie jak: (objectCategory = komputer) powinno wystarczyć. -Jim

5

Co EKS sugerowane jest prawidłowe, ale wykonuje trochę powolny.

Powodem tego jest połączenie z GetDirectoryEntry() dla każdego wyniku. Spowoduje to utworzenie obiektu DirectoryEntry, który jest potrzebny tylko wtedy, gdy trzeba zmodyfikować obiekt Active Directory (AD). Jest OK, jeśli zapytanie zwróci pojedynczy obiekt, ale podczas wyświetlania wszystkich obiektów w AD znacznie obniża wydajność.

Jeśli potrzebujesz tylko zapytać AD, lepiej użyć po prostu kolekcji Properties obiektu wynikowego. Poprawi to wydajność kodu kilka razy.

to wyjaśnione w documentation for SearchResult class:

instancje klasy SearchResult są bardzo podobne do przypadków DirectoryEntry klasy. Zasadniczą różnicą jest to, że klasa DirectoryEntry pobiera swoje informacje z Active Directory Domain Services hierarchii za każdym razem nowy obiekt jest dostępnego, natomiast dane dla SearchResult jest już dostępny w na SearchResultCollection, gdzie zostanie zwrócony z kwerendy, która jest wykonywana z klasą DirectorySearcher.

Oto przykład, w jaki sposób korzystać z Properties kolekcję:

public static List<string> GetComputers() 
{ 
    List<string> computerNames = new List<string>(); 

    using (DirectoryEntry entry = new DirectoryEntry("LDAP://YourActiveDirectoryDomain.no")) { 
     using (DirectorySearcher mySearcher = new DirectorySearcher(entry)) { 
      mySearcher.Filter = ("(objectClass=computer)"); 

      // No size limit, reads all objects 
      mySearcher.SizeLimit = 0; 

      // Read data in pages of 250 objects. Make sure this value is below the limit configured in your AD domain (if there is a limit) 
      mySearcher.PageSize = 250; 

      // Let searcher know which properties are going to be used, and only load those 
      mySearcher.PropertiesToLoad.Add("name"); 

      foreach(SearchResult resEnt in mySearcher.FindAll()) 
      { 
       // Note: Properties can contain multiple values. 
       if (resEnt.Properties["name"].Count > 0) 
       { 
        string computerName = (string)resEnt.Properties["name"][0]; 
        computerNames.Add(computerName); 
       } 
      } 
     } 
    } 

    return computerNames; 
} 

Documentation for SearchResult.Properties

Należy pamiętać, że właściwości mogą mieć wiele wartości, dlatego używamy Properties["name"].Count sprawdzić numer wartości.

Aby jeszcze bardziej poprawić sytuację, skorzystaj z kolekcji PropertiesToLoad, aby poinformować wyszukiwarkę, z jakich właściwości zamierzasz korzystać wcześniej. Dzięki temu osoba wyszukująca może jedynie odczytać dane, które faktycznie będą używane.

Uwaga że DirectoryEntry i DirectorySearcher obiekty powinny być prawidłowo usunięte w celu uwolnienia wszystkich zasobów używanych. Najlepiej zrobione z klauzula using.

Powiązane problemy