怎样才能更好地我使用C#查询在Active Directory中的多个域?(How can I be

2019-06-23 20:49发布

我试图扩大仅在当前登录搜索域在AD搜索所有域的LDAP / AD搜索。 该方法采用与查询并返回字符串中并返回LDAPInformation对象。

当我问,有没有更好的方法来搜索该名称不是这样? 这是用户不友好由于需要,如果想找一个人按姓氏(例如:李四*)使用通配符。

    public static LDAPInformation[] GetGlobalAddressListVIAName(string nameQuery)
    {
        var currentForest = Forest.GetCurrentForest();
        var globalCatalog = currentForest.FindGlobalCatalog();

        using (var searcher = globalCatalog.GetDirectorySearcher())
        {
            using (var entry = new DirectoryEntry(searcher.SearchRoot.Path))
            {
                searcher.Filter = "(&(mailnickname=*)(objectClass=user)(displayName=" + nameQuery + "))";
                searcher.PropertyNamesOnly = true;
                searcher.SearchScope = SearchScope.Subtree;
                searcher.Sort.Direction = SortDirection.Ascending;
                searcher.Sort.PropertyName = "displayName";
                return searcher.FindAll().Cast<SearchResult>().Select(result => new LDAPInformation(result.GetDirectoryEntry())).ToArray();
            }
        }
    }

这里是对象:

    class LDAPInformation
{
    internal LDAPInformation(DirectoryEntry entry)
    {
        //Section: HASH
        this.sAMAccountName = (string)entry.Properties["sAMAccountName"].Value;

        //Section: Email
        this.Mail = (string)entry.Properties["mail"].Value;

        //Section: Organziation
        this.Description = (string)entry.Properties["description"].Value;
        this.Company = (string)entry.Properties["company"].Value;
        this.Title = (string)entry.Properties["title"].Value;
        this.Department = (string)entry.Properties["department"].Value;

        //Section: Name
        this.DisplayName = (string)entry.Properties["displayName"].Value;
        this.FirstName = (string)entry.Properties["firstName"].Value;
        this.MiddleName = (string)entry.Properties["middleName"].Value;
        this.LastName = (string)entry.Properties["lastName"].Value;

        //Section: Address
        this.StreetAddress = (string)entry.Properties["streetAddress"].Value;
        this.City = (string)entry.Properties["city"].Value;
        this.State = (string)entry.Properties["state"].Value;
        this.PostalCode = (string)entry.Properties["postalCode"].Value;
        this.TelephoneNumber = (string)entry.Properties["telephoneNumber"].Value;
    }

    public string DisplayName
    {
        get;
        private set;
    }

    public string Mail
    {
        get;
        private set;
    }

    public string sAMAccountName
    {
        get;
        private set;
    }

    public string Description
    {
        get;
        private set;
    }

    public string Company
    {
        get;
        private set;
    }

    public string Title
    {
        get;
        private set;
    }

    public string Department
    {
        get;
        private set;
    }

    public string FirstName
    {
        get;
        private set;
    }

    public string MiddleName
    {
        get;
        private set;
    }

    public string LastName
    {
        get;
        private set;
    }

    public string StreetAddress
    {
        get;
        private set;
    }

    public string City
    {
        get;
        private set;
    }

    public string State
    {
        get;
        private set;
    }

    public string PostalCode
    {
        get;
        private set;
    }

    public string TelephoneNumber
    {
        get;
        private set;
    }
}

Answer 1:

查询全局编录是正确的做法。

你可能想看看Ambigous名称解析(ANR) - http://support.microsoft.com/kb/243299 。



Answer 2:

@布赖恩德斯蒙德和@lordzero。 可能有点晚了这里的一部分,但我刚刚一直致力于这一类的东西,我自己最近这么认为我分享。

在回答你的问题“什么是你的搜索根?”,lordzero,这里是你可以做从AD服务器发现它是什么不知道他们。域名注册的PC会知道AD基础设施/森林等。

首先,创建了“GC:// RootDSE的”一个DirectoryEntry从你提取命名上下文,rootDomainNamingContext或其他。 你可以转储出第一根DSE的DirectoryEntry的所有属性,看看有什么可用。

这是我的实施,我们使用一个目录服务的服务提供商。

这是从DirectorySearcherWrapper类取

我有一个成员变种。 并创建实例的构造函数。

DirectorySearcher directorySearcher;

在我的初始化方法,我这样做

        using (DirectoryEntry directoryEntry = new DirectoryEntry(DirectoryConstants.RootDSE))
        {
            // Create a Global Catalog Directory Service Searcher
            string strRootName = directoryEntry.Properties[DirectoryConstants.RootDomainNamingContext].Value.ToString();
            using (DirectoryEntry usersBinding = new DirectoryEntry(DirectoryConstants.GlobalCatalogProtocol + strRootName))
            {
                directorySearcher.SearchRoot = usersBinding;
                directorySearcher.ClientTimeout = timeout;
                directorySearcher.CacheResults = true;
                result = true;
                initialized = true;
            }
        }

DirectoryConstants类属性

public static string RootDSE { get { return @"GC://rootDSE"; } }
public static string RootDomainNamingContext { get { return "rootDomainNamingContext"; } }
public static string GlobalCatalogProtocol { get { return @"GC://"; } }

我敢肯定,这只是为域用户的作品登录到域注册的PC。 验证是在幕后自动处理。 如果您的用户登录到本地帐户或机器是不是一个域,你很可能会得到一个DirectoryServicesCOMException。

希望这可以帮助。 沟“用”结构,如果你不打扰关于处置和了StyleCop /声纳编码违规!

其中上面的代码驻留的DirectorySearcherWrapper类然后由服务营业者代码使用。 它分离这样的,因此它可以很容易地因为有嘲笑了不能保证构建的机器被注册到时候执行单元测试的域。

......大部分来自MSDN / .NET文档。



文章来源: How can I better query multiple domains in Active Directory using C#?