我如何通过 C# 以编程方式获取 Active Directory 林的根
How can i programmatically get the root of an Active Directory Forest via C#
我的客户有一个巨大的 Active Directory 林。例如:
根目录
company.com
de.company.com
us.company.com
in.company.com
xx.company.com
当我得到当前用户时,我得到 domainname\username
。当我获取域名并想在这个域中搜索世界上的其他用户时,我不能因为我需要知道 company.com 才能进行目录搜索。
在 C# 中有没有办法获取我使用 DirectorySearcher 或任何其他 C# 方法查询 AD 的根对象?
要获取用户的根对象,请使用 属性 或属性 distinguished name 来确定 Active Direcotry 中的完全限定路径。从右边读取结构并提取根元素。
E. G。 cn=John Doe, ou=People, dc=sun.com
可以从 RootDSE 分区获取根目录林名称。查看 rootDomainNamingContext 属性。这将 return 您的林根域。我不建议从用户 DN 中提取林名称,因为如果您在一个林中有 2 个域树,它就不起作用。第二个选项是在当前域的全局目录中搜索用户。全局目录包含整个林中所有用户的部分副本
下面的代码对全局目录执行搜索。我有 2 个域,在我的林中,所以 return 我有 2 个用户。请注意,您将不得不处理多个结果 returned:
var forest = Forest.GetCurrentForest();
var globalCatalog = GlobalCatalog.FindOne(new DirectoryContext(DirectoryContextType.Forest, forest.Name));
using (var connection = new LdapConnection(new LdapDirectoryIdentifier(globalCatalog.Name, 3268)))
{
var entries = new List<SearchResultEntry>();
var searchRequest = new SearchRequest(string.Empty, "(samaccountname=administrator)", SearchScope.Subtree, null);
var searchOptionsControl = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
searchRequest.Controls.Add(searchOptionsControl);
var pageResultRequestControl = new PageResultRequestControl(1000);
searchRequest.Controls.Add(pageResultRequestControl);
do
{
var response = (SearchResponse)connection.SendRequest(searchRequest);
if (response != null)
{
if (response.ResultCode != ResultCode.Success)
{
throw new ActiveDirectoryOperationException(response.ErrorMessage, (int) response.ResultCode);
}
foreach (var c in response.Controls.OfType<PageResultResponseControl>())
{
pageResultRequestControl.Cookie = c.Cookie;
break;
}
entries.AddRange(response.Entries.Cast<SearchResultEntry>());
}
}
while (pageResultRequestControl.Cookie != null && pageResultRequestControl.Cookie.Length > 0);
}
关于这段代码的几点说明:
1.当然这段代码不是生产代码。你可以写更通用的LdapSearcher,比如一个可以查到here。如果需要,您可以制作此搜索器的同步版本。
2. 我强烈建议在基于服务的应用程序中使用 LdapConnection 而不是 DirectorySearcher,因为在企业环境中使用 DirectorySearcher 会导致内存泄漏和其他 issues
我的客户有一个巨大的 Active Directory 林。例如:
根目录
company.com
de.company.com
us.company.com
in.company.com
xx.company.com
当我得到当前用户时,我得到 domainname\username
。当我获取域名并想在这个域中搜索世界上的其他用户时,我不能因为我需要知道 company.com 才能进行目录搜索。
在 C# 中有没有办法获取我使用 DirectorySearcher 或任何其他 C# 方法查询 AD 的根对象?
要获取用户的根对象,请使用 属性 或属性 distinguished name 来确定 Active Direcotry 中的完全限定路径。从右边读取结构并提取根元素。
E. G。 cn=John Doe, ou=People, dc=sun.com
可以从 RootDSE 分区获取根目录林名称。查看 rootDomainNamingContext 属性。这将 return 您的林根域。我不建议从用户 DN 中提取林名称,因为如果您在一个林中有 2 个域树,它就不起作用。第二个选项是在当前域的全局目录中搜索用户。全局目录包含整个林中所有用户的部分副本
下面的代码对全局目录执行搜索。我有 2 个域,在我的林中,所以 return 我有 2 个用户。请注意,您将不得不处理多个结果 returned:
var forest = Forest.GetCurrentForest();
var globalCatalog = GlobalCatalog.FindOne(new DirectoryContext(DirectoryContextType.Forest, forest.Name));
using (var connection = new LdapConnection(new LdapDirectoryIdentifier(globalCatalog.Name, 3268)))
{
var entries = new List<SearchResultEntry>();
var searchRequest = new SearchRequest(string.Empty, "(samaccountname=administrator)", SearchScope.Subtree, null);
var searchOptionsControl = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);
searchRequest.Controls.Add(searchOptionsControl);
var pageResultRequestControl = new PageResultRequestControl(1000);
searchRequest.Controls.Add(pageResultRequestControl);
do
{
var response = (SearchResponse)connection.SendRequest(searchRequest);
if (response != null)
{
if (response.ResultCode != ResultCode.Success)
{
throw new ActiveDirectoryOperationException(response.ErrorMessage, (int) response.ResultCode);
}
foreach (var c in response.Controls.OfType<PageResultResponseControl>())
{
pageResultRequestControl.Cookie = c.Cookie;
break;
}
entries.AddRange(response.Entries.Cast<SearchResultEntry>());
}
}
while (pageResultRequestControl.Cookie != null && pageResultRequestControl.Cookie.Length > 0);
}
关于这段代码的几点说明: 1.当然这段代码不是生产代码。你可以写更通用的LdapSearcher,比如一个可以查到here。如果需要,您可以制作此搜索器的同步版本。 2. 我强烈建议在基于服务的应用程序中使用 LdapConnection 而不是 DirectorySearcher,因为在企业环境中使用 DirectorySearcher 会导致内存泄漏和其他 issues