列出活动目录中的所有计算机

时间:2009-10-22 07:36:11

标签: c# active-directory ldap

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

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

3 个答案:

答案 0 :(得分:25)

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

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 :(得分:9)

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子句完成。

答案 2 :(得分:1)

像:(objectCategory=computer)这样的LDAP查询可以解决问题。