在 C# 中查询 LDAP 以获取计算机列表
Querying LDAP in C# to get list of computers
我在 Windows Forms C# 项目中使用 LDAP。
我创建了一个 CheckListBox,并开始创建一个方法来查询我所有计算机的 Active Directory 环境。
方法是:
public string ComputerList()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");
DirectorySearcher computerSercher = new DirectorySearcher(rootDSE);
computerSercher.PageSize = 10000;
computerSercher.Filter = "(&(objectClass=computer))";
}
正如我所说,我也有一个 CheckListBox。
我想做的是获得查询结果和找到的每台计算机。将其添加到 CheckListBox 的项目 属性。
但我什至不知道如何接近结果。它不像 PowerShell 那样提供对象列表...
谢谢
你快到了。一些事情:
- 将页面大小设置为 1000。AD 不会一次给你超过 1000,所以如果你将它设置为超过 1000,你只会得到 1000(如果
DirectorySearcher
没有如果不返回它认为是整页的内容,它将停止询问)
- 将要读取的属性添加到
PropertiesToLoad
集合中。如果你不添加任何东西,它会给你每个属性一个值,这是一堆你不会使用的不必要的数据。您可能只想查看 cn
属性(通用名称)。
- 使用
FindAll()
得到结果。确保将其包装在 using
语句中以防止内存泄漏(文档中是这样说的)。
- 当您查看结果时,每个 属性 都显示为一个数组,无论是否在 AD 中。所以在大多数情况下你需要使用
[0]
。供将来参考(此处不适用):如果 AD 中未设置 属性,则它根本不会出现在 Properties
集合中,因此,对于可选属性,您必须使用Properties.Contains()
先看看有没有
根据您所拥有的,这里有一个方法可以 return 计算机名称列表:
public IEnumerable<string> ComputerList()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");
DirectorySearcher computerSercher = new DirectorySearcher(rootDSE)
{
PageSize = 1000,
Filter = "(&(objectClass=computer))"
};
computerSercher.PropertiesToLoad.Add("cn");
using (var results = computerSercher.FindAll())
{
foreach (SearchResult result in results)
{
yield return (string) result.Properties["cn"][0];
}
}
}
更新:在您的评论中回答您的问题:
yield
basically tells it to "add this item to the collection that will be returned". There is a little more going on in the background, which you can read about here。但用最简单的话来说,它使您不必创建自己的列表、将项目添加到该列表和 return 列表。
- 我将 return 类型从
string
更改为 IEnumerable<string>
因为您从搜索中得到了多个结果,所以我假设您想要 return 所有这些结果。此方法将为您提供计算机名称列表,而不仅仅是一个计算机名称。
FindAll()
return一个SearchResultCollection
。出于某种我不知道的原因,foreach
中从 SearchResultCollection
编辑的对象 return 显示为 object
。所以你需要明确地将它们转换为 SearchResult
才能使用它们。
我在 Windows Forms C# 项目中使用 LDAP。
我创建了一个 CheckListBox,并开始创建一个方法来查询我所有计算机的 Active Directory 环境。
方法是:
public string ComputerList()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");
DirectorySearcher computerSercher = new DirectorySearcher(rootDSE);
computerSercher.PageSize = 10000;
computerSercher.Filter = "(&(objectClass=computer))";
}
正如我所说,我也有一个 CheckListBox。
我想做的是获得查询结果和找到的每台计算机。将其添加到 CheckListBox 的项目 属性。
但我什至不知道如何接近结果。它不像 PowerShell 那样提供对象列表...
谢谢
你快到了。一些事情:
- 将页面大小设置为 1000。AD 不会一次给你超过 1000,所以如果你将它设置为超过 1000,你只会得到 1000(如果
DirectorySearcher
没有如果不返回它认为是整页的内容,它将停止询问) - 将要读取的属性添加到
PropertiesToLoad
集合中。如果你不添加任何东西,它会给你每个属性一个值,这是一堆你不会使用的不必要的数据。您可能只想查看cn
属性(通用名称)。 - 使用
FindAll()
得到结果。确保将其包装在using
语句中以防止内存泄漏(文档中是这样说的)。 - 当您查看结果时,每个 属性 都显示为一个数组,无论是否在 AD 中。所以在大多数情况下你需要使用
[0]
。供将来参考(此处不适用):如果 AD 中未设置 属性,则它根本不会出现在Properties
集合中,因此,对于可选属性,您必须使用Properties.Contains()
先看看有没有
根据您所拥有的,这里有一个方法可以 return 计算机名称列表:
public IEnumerable<string> ComputerList()
{
DirectoryEntry rootDSE = new DirectoryEntry("LDAP://MyDomain.Local");
DirectorySearcher computerSercher = new DirectorySearcher(rootDSE)
{
PageSize = 1000,
Filter = "(&(objectClass=computer))"
};
computerSercher.PropertiesToLoad.Add("cn");
using (var results = computerSercher.FindAll())
{
foreach (SearchResult result in results)
{
yield return (string) result.Properties["cn"][0];
}
}
}
更新:在您的评论中回答您的问题:
yield
basically tells it to "add this item to the collection that will be returned". There is a little more going on in the background, which you can read about here。但用最简单的话来说,它使您不必创建自己的列表、将项目添加到该列表和 return 列表。- 我将 return 类型从
string
更改为IEnumerable<string>
因为您从搜索中得到了多个结果,所以我假设您想要 return 所有这些结果。此方法将为您提供计算机名称列表,而不仅仅是一个计算机名称。 FindAll()
return一个SearchResultCollection
。出于某种我不知道的原因,foreach
中从SearchResultCollection
编辑的对象 return 显示为object
。所以你需要明确地将它们转换为SearchResult
才能使用它们。