C# 如何通过C以编程方式获取Active Directory林的根#

C# 如何通过C以编程方式获取Active Directory林的根#,c#,active-directory,directoryservices,C#,Active Directory,Directoryservices,我的客户首先拥有一个巨大的Active Directory。例如: 根 当我得到当前用户时,我得到的是domainname\username。当我获取域名并想在这个域中搜索世界上的其他用户时,我不能因为我需要知道company.com来进行目录搜索 在C#中是否有方法获取我与DirectorySearcher或任何其他C#方法一起用于查询AD的根对象?要获取用户的根对象,请使用属性或属性确定Active Directory中的完全限定路径。从右侧读取结构并提取根元素 例如cn=johndoe,o

我的客户首先拥有一个巨大的Active Directory。例如:

当我得到当前用户时,我得到的是
domainname\username
。当我获取域名并想在这个域中搜索世界上的其他用户时,我不能因为我需要知道company.com来进行目录搜索


在C#中是否有方法获取我与DirectorySearcher或任何其他C#方法一起用于查询AD的根对象?

要获取用户的根对象,请使用属性或属性确定Active Directory中的完全限定路径。从右侧读取结构并提取根元素

例如
cn=johndoe,ou=People,dc=sun.com


根林名称可以从RootDSE分区中包含。查看rootDomainNamingContext属性。这将返回您的林根域。我不建议从用户DN中提取林名称,因为在一个林中有两个域树的情况下,它将不起作用。第二个选项是在当前域的全局目录中搜索用户。全局编录包含整个林中所有用户的部分副本

下面的代码在全局目录上执行搜索。我有2个域,在我的林中,所以它返回我2个用户。请注意,您必须处理返回的多个结果:

        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);
        }
var-forest=forest.GetCurrentForest();
var globalCatalog=globalCatalog.FindOne(新的DirectoryContext(DirectoryContextType.Forest,Forest.Name));
使用(var connection=new LdapConnection(new LdapDirectoryIdentifier(globalCatalog.Name,3268)))
{
var entries=新列表();
var searchRequest=newsearchrequest(string.Empty,“(samaccountname=administrator)”,SearchScope.Subtree,null);
var searchoptioncontrol=新的searchoptioncontrol(System.DirectoryServices.Protocols.SearchOption.DomainScope);
searchRequest.Controls.Add(searchoptions控制);
var pageResultRequestControl=新的pageResultRequestControl(1000);
searchRequest.Controls.Add(pageResultRequestControl);
做
{
var response=(SearchResponse)connection.SendRequest(searchRequest);
if(响应!=null)
{
if(response.ResultCode!=ResultCode.Success)
{
抛出新的ActiveDirectoryOperationException(response.ErrorMessage,(int)response.ResultCode);
}
foreach(varc在response.Controls.OfType()中)
{
pageResultRequestControl.Cookie=c.Cookie;
打破
}
entries.AddRange(response.entries.Cast());
}
}
while(pageResultRequestControl.Cookie!=null&&pageResultRequestControl.Cookie.Length>0);
}
关于此代码的几个注释: 1.当然,这段代码不是生产代码。您可以编写更通用的LdapSearcher,例如,可以找到一个。如果需要,您可以创建此搜索程序的同步版本。
2.我强烈建议在基于服务的应用程序中使用LdapConnection而不是DirectorySearcher,因为在企业环境中使用DirectorySearcher会导致内存泄漏和其他问题

您是否尝试过使用可分辨名称?可分辨名称?但如果您有类似于
dc=de,dc=eu,dc=company,dc=com的内容呢(de.eu.company.com)并且您只需要root
dc=company,dc=com
(company.com)?@STORM只需读取当前用户的可分辨名称和
RegEx
Split
Substring
值。嗯,好的,我会用rootDomainNamingContext试试。这听起来不错,网上的示例是透明的/可以理解的,可能是我正在搜索的东西,但你能给我多一点信息吗o在全局编录上?全局编录是一个域控制器,它存储所有林对象的特定属性。对于每个属性,Active Directory架构指定该属性是否存储在全局编录中。您可以查看System.DirectoryServices.ActiveDirectory.forest类,该类为您提供所有可用全局编录的信息talogs。如果您不知道搜索到的用户所属的域名,则此方法适用。要查询全局编录,您需要指定GC://而不是LDAP://如果全局编录中缺少搜索到的属性,您仍然可以创建林类,然后从此类获取林域列表,并在每个域中搜索用户如果您向我提供了有关如何搜索用户的更多详细信息,即根据您要从广告中查询的属性和信息,我可以给您提供更具体的建议给定:姓名或姓氏或帐户名或电子邮件地址。因为我是根据上述信息之一搜索用户,我没有域名。这是一个SP.NET MVC应用程序运行在带有IIS的Windows服务器上,该服务器已加入域。我还有一个经典的WinForms解决方案,其中我有完全相同的要求。桌面应用程序运行在用户客户端上,该客户端也连接到域。我需要使用户能够根据筛选信息搜索用户如果你能给我一个具体的建议,那就太好了。
        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);
        }