【问题标题】:How to search in multiple domains using System.DirectoryServices.AccountManagement?如何使用 System.DirectoryServices.AccountManagement 在多个域中搜索?
【发布时间】:2012-05-05 06:27:41
【问题描述】:

我拥有三个或更多域,例如 main.comsub.main.comsub2.main.com

我有一个代码:

using (PrincipalContext ctx = 
    new PrincipalContext(ContextType.Domain, "ADServer", 
    "dc=main,dc=com", ContextOptions.Negotiate))
{
    UserPrincipal u = new UserPrincipal(ctx);
    u.UserPrincipalName = "*" + mask + "*";

    using (PrincipalSearcher ps = new PrincipalSearcher(u))
    {
       PrincipalSearchResult<Principal> results = ps.FindAll();
       List<ADUser> lst = new List<ADUser>();

       foreach (var item in results.Cast<UserPrincipal>().Take(15))
       {
           byte[] sid = new byte[item.Sid.BinaryLength];
           item.Sid.GetBinaryForm(sid, 0);

           ADUser us = new ADUser()
           {
               Sid = sid,
               Account = item.SamAccountName,
               FullName = item.DisplayName
           };

           lst.Add(us);
       }

    }

    return lst;
}

但它只在一个域内搜索:main.com

如何一次搜索所有域中的记录?

【问题讨论】:

  • 我认为您不能一次在多个域中进行搜索。您需要“序列化”您的搜索。
  • 你的意思是我必须知道域并用循环搜索它们吗?

标签: c# active-directory ldap


【解决方案1】:

您应该使用 GC 而不是 LDAP。它沿着整个域森林搜索

var path = "GC://DC=main,DC=com";

try
{
    using (var root = new DirectoryEntry(path, username, password))
    {
        var searchFilter = string.Format("(&(anr={0})(objectCategory=user)(objectClass=user))", mask);
        using (var searcher = new DirectorySearcher(root, searchFilter, new[] { "objectSid", "userPrincipalName" }))
        {
            var results = searcher.FindAll();
            foreach (SearchResult item in results)
            {
                //What ever you do
            }
        }
    }
}

catch (DirectoryServicesCOMException)
{
    // username or password are wrong
}

【讨论】:

  • 谢谢,这就像一个魅力,比接受的答案更简单。
  • 对可见性投了赞成票。经过大量资源搜索后的最佳答案
【解决方案2】:

这是一种从根目录中查找所有域的方法:

/* Retreiving RootDSE
 */
string ldapBase = "LDAP://DC_DNS_NAME:389/";
string sFromWhere = ldapBase + "rootDSE";
DirectoryEntry root = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD");
string configurationNamingContext = root.Properties["configurationNamingContext"][0].ToString();

/* Retreiving the root of all the domains
 */
sFromWhere = ldapBase + configurationNamingContext;
DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "AdminLogin", "PWD");

DirectorySearcher dsLookForDomain = new DirectorySearcher(deBase);
dsLookForDomain.Filter = "(&(objectClass=crossRef)(nETBIOSName=*))";
dsLookForDomain.SearchScope = SearchScope.Subtree;
dsLookForDomain.PropertiesToLoad.Add("nCName");
dsLookForDomain.PropertiesToLoad.Add("dnsRoot");

SearchResultCollection srcDomains = dsLookForDomain.FindAll();

foreach (SearchResult aSRDomain in srcDomains)
{
}

然后foreach域,你可以自己找你需要的。

【讨论】:

  • 在我的情况下没有:389 端口。
  • 您应该在您的域中找到 GC。
  • 谢谢,new DirectoryEntry("LDAP://server IP/DC=my-domain,DC=com", ...) 工作正常。
【解决方案3】:

要实际使用 System.DirectoryServices.AccountManagement 进行搜索,请指定域:

new PrincipalContext(ContextType.Domain, "xyz.mycorp.com:3268", "DC=mycorp,DC=com");

When do I need a Domain Name and a Domain Container to create a PrincipalContext?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-27
    • 2018-05-29
    • 2013-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多