【问题标题】:List all computers in active directory列出活动目录中的所有计算机
【发布时间】:2009-10-22 07:36:11
【问题描述】:

我想知道如何从活动目录中获取所有计算机/机器/pc 的列表?

(试图让这个页面成为搜索引擎的诱饵,会自己回复。如果有人有更好的回复,我会接受)

【问题讨论】:

    标签: c# active-directory ldap


    【解决方案1】:

    如果您有一个非常大的域,或者您的域配置了每次搜索可以返回多少项目的限制,您可能必须使用分页。

    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;
    }
    

    【讨论】:

      【解决方案2】:

      EKS 的建议是正确,但执行起来有点

      原因是每个结果都调用GetDirectoryEntry()。这将创建一个DirectoryEntry 对象,仅当您需要修改活动目录 (AD) 对象时才需要该对象。如果您的查询将返回单个对象,这没关系,但是当列出 AD 中的所有对象时,这会大大降低性能。

      如果只需要查询AD,最好只使用结果对象的Properties集合。这将使代码的性能提高数倍。

      这在documentation for SearchResult class中有解释:

      SearchResult 类的实例与 DirectoryEntry 班级。关键的区别在于 DirectoryEntry 类从 Active 中检索其信息 每次有新对象时的目录域服务层次结构 已访问,而 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 集合让搜索者提前知道您将使用哪些属性。这允许搜索者仅读取实际将要使用的数据。

      请注意,DirectoryEntryDirectorySearcher 对象应该 妥善处置,以释放所有使用的资源。最好的 使用using 子句完成。

      【讨论】:

        【解决方案3】:

        如下 LDAP 查询:(objectCategory=computer) 应该可以解决问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-16
          • 1970-01-01
          • 2011-07-06
          • 1970-01-01
          相关资源
          最近更新 更多