繁体   English   中英

从Active Directory获取所有直接报告

[英]Getting all direct Reports from Active Directory

我试图通过递归方式通过Active Directory获取用户的所有直接报告。 因此,给定一个用户,我最终会得到一个列表,其中列出了所有以此人为经理的人或者有一个人作为经理,他有一个人作为经理......他最终将输入用户作为经理。

我目前的尝试相当缓慢:

private static Collection<string> GetDirectReportsInternal(string userDN, out long elapsedTime)
{
    Collection<string> result = new Collection<string>();
    Collection<string> reports = new Collection<string>();

    Stopwatch sw = new Stopwatch();
    sw.Start();

    long allSubElapsed = 0;
    string principalname = string.Empty;

    using (DirectoryEntry directoryEntry = new DirectoryEntry(string.Format("LDAP://{0}",userDN)))
    {
        using (DirectorySearcher ds = new DirectorySearcher(directoryEntry))
        {
            ds.SearchScope = SearchScope.Subtree;
            ds.PropertiesToLoad.Clear();
            ds.PropertiesToLoad.Add("directReports");
            ds.PropertiesToLoad.Add("userPrincipalName");
            ds.PageSize = 10;
            ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
            SearchResult sr = ds.FindOne();
            if (sr != null)
            {
                principalname = (string)sr.Properties["userPrincipalName"][0];
                foreach (string s in sr.Properties["directReports"])
                {
                    reports.Add(s);
                }
            }
        }
    }

    if (!string.IsNullOrEmpty(principalname))
    {
        result.Add(principalname);
    }

    foreach (string s in reports)
    {
        long subElapsed = 0;
        Collection<string> subResult = GetDirectReportsInternal(s, out subElapsed);
        allSubElapsed += subElapsed;

        foreach (string s2 in subResult)
        {
        result.Add(s2);
        }
    }



    sw.Stop();
    elapsedTime = sw.ElapsedMilliseconds + allSubElapsed;
    return result;
}

本质上,此函数将一个可分辨的名称作为输入(CN = Michael Stum,OU = test,DC = sub,DC = domain,DC = com),因此,对ds.FindOne()的调用很慢。

我发现搜索userPrincipalName要快得多。 我的问题:sr.Properties [“directReports”]只是一个字符串列表,这就是distinguishedName,它似乎很难搜索。

我想知道,有没有一种快速的方法来在distinguishedName和userPrincipalName之间进行转换? 或者,如果我只使用distinguishedName,那么搜索用户的方法是否更快?

编辑:谢谢你的回答! 搜索Manager-Field将功能从90秒提高到4秒。 这是新的和改进的代码,它更快,更易读(请注意,elapsedTime功能中很可能存在错误,但该函数的实际核心有效):

private static Collection<string> GetDirectReportsInternal(string ldapBase, string userDN, out long elapsedTime)
{
    Collection<string> result = new Collection<string>();

    Stopwatch sw = new Stopwatch();
    sw.Start();
    string principalname = string.Empty;

    using (DirectoryEntry directoryEntry = new DirectoryEntry(ldapBase))
    {
        using (DirectorySearcher ds = new DirectorySearcher(directoryEntry))
        {
            ds.SearchScope = SearchScope.Subtree;
            ds.PropertiesToLoad.Clear();
            ds.PropertiesToLoad.Add("userPrincipalName");
            ds.PropertiesToLoad.Add("distinguishedName");
            ds.PageSize = 10;
            ds.ServerPageTimeLimit = TimeSpan.FromSeconds(2);
            ds.Filter = string.Format("(&(objectCategory=user)(manager={0}))",userDN);

            using (SearchResultCollection src = ds.FindAll())
            {
                Collection<string> tmp = null;
                long subElapsed = 0;
                foreach (SearchResult sr in src)
                {
                    result.Add((string)sr.Properties["userPrincipalName"][0]);
                    tmp = GetDirectReportsInternal(ldapBase, (string)sr.Properties["distinguishedName"][0], out subElapsed);
                    foreach (string s in tmp)
                    {
                    result.Add(s);
                    }
                }
            }
          }
        }
    sw.Stop();
    elapsedTime = sw.ElapsedMilliseconds;
    return result;
}

首先,如果您已经拥有要查找的DN,则无需将Scope设置为“子树”。

此外,如何查找“manager”属性是您查找的人的所有对象,然后迭代它们。 这应该通常比其他方式更快。

(&(objectCategory=user)(manager=<user-dn-here>))

编辑:以下是重要的,但到目前为止只在答案的评论中提到:

如上所示构建过滤器字符串时,存在使用对DN有效的字符将其分解的风险,但在过滤器中具有特殊含义。 这些必须转义

*   as  \2a
(   as  \28
)   as  \29
\   as  \5c
NUL as  \00
/   as  \2f

// Arbitrary binary data can be represented using the same scheme.

编辑:设置SearchRoot到对象的DN和SearchScope ,以Base也就是拉一个对象了AD的快速方式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM