2009-10-22 19 views

ответ

23

Если у вас есть очень большой домен, или ваш домен ограничение настроен как как многие предметы могут быть возвращены за поиск, возможно, вам придется использовать пейджинг.

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

Запрос на LDAP как: (objectCategory = computer) должен делать трюк. -Джим

5

Что EKS предложил это правильно, но выполняет немного медленно.

Причиной тому является вызов GetDirectoryEntry() по каждому результату. Это создает объект DirectoryEntry, который необходим только в том случае, если вам нужно изменить объект активной директории (AD). Это нормально, если ваш запрос вернет один объект, но при перечислении всего объекта в AD это значительно ухудшает производительность.

Если вам нужно только запросить AD, лучше всего использовать коллекцию результатов объекта Properties. Это позволит повысить производительность кода несколько раз.

Это объясняется в documentation for SearchResult class:

Экземпляры SearchResult класса очень похожи на экземпляры DirectoryEntry класса. Важное отличие является то, что DirectoryEntry класса извлекает информацию из активной иерархии доменных служб каждый раз, когда новый объект, доступ к , в то время как данные для SearchResult уже доступны в в SearchResultCollection, где он получает вернулись из запроса, выполняется с классом DirectorySearcher.

Вот пример о том, как использовать Properties коллекции:

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

Обратите внимание, что свойства могут иметь несколько значений, поэтому мы используем Properties["name"].Count, чтобы проверить номер значений.

Чтобы улучшить ситуацию еще больше, используйте коллекцию PropertiesToLoad, чтобы узнать, какие свойства вы собираетесь использовать заранее. Это позволяет поисковику считывать только данные, которые будут использоваться.

Обратите внимание, что DirectoryEntry и DirectorySearcher объекты должны быть надлежащим образом утилизировать, чтобы освободить все ресурсы, используемые. Лучшее сделано с оговоркой using.

Смежные вопросы