4

好的,使用活动目录,我剩下的一个要求是拉回给定组中的所有用户并获取他们的详细信息 - 名字、姓氏、用户名、电子邮件。

在阅读了这个之后,我惊讶地发现似乎没有一种方法可以有效地做到这一点。我已经制定了两种获得结果的方法,但似乎都非常浪费。

首先是搜索组的成员,如下所示:

        DirectoryEntry searchRoot = new DirectoryEntry("LDAP://" + server, username, password);
        DirectorySearcher search = new DirectorySearcher(searchRoot);
        search.Filter = string.Format("(|(CN={0})(CN={1}))", "Group1", "Group2");

        search.PropertiesToLoad.Add("member");
        SearchResultCollection results = search.FindAll();

这会返回一个包含用户名和仅用户名的结果。您可以将其分解为一组单独的用户名,但是要获取每个用户的详细信息,您必须根据每个名称再次搜索 AD。

另一种方法是这样做:

   DirectoryEntry searchRoot = new DirectoryEntry("LDAP://" + server, username, password);
    DirectorySearcher search = new DirectorySearcher(searchRoot);
    search.Filter = string.Format("(&(&(objectClass=user)(objectCategory=person))(memberOf=*))");

    search.PropertiesToLoad.Add("memberOf");
    search.PropertiesToLoad.Add("name");
    search.PropertiesToLoad.Add("mail");
    search.PropertiesToLoad.Add("displayName");

    SearchResultCollection mySearchResultColl = search.FindAll();

    foreach (SearchResult result in mySearchResultColl)
    {
        foreach (string prop in result.Properties["memberOf"])
        {
            if (prop.Contains("Group1") || prop.Contain("Group2"))
            {
               //add user to list
            }
        }
    }

这让我得到了我想要的,但涉及检索每个活动目录用户,然后遍历集合以找到匹配的用户。这在我的小测试目录上运行良好,但我不寒而栗地想到它在拥有数千名用户的系统上会有多慢。

我知道你可以使用 PrinicpalContext 对象来做我需要的事情,但我可以说只有当代码在同一个域中运行时才有效,我不能保证。我需要能够跨域查询。

有没有更好的方法来做到这一点?还是我只需要解决性能问题?

4

2 回答 2

2

如果只需要查找直接成员,可以使用属性范围查询(ASQ)。这需要 2003 年的域/林功能级别(忘记域或林)。

DirectoryEntry groupEntry = new DirectoryEntry("LDAP://<server>/<group DN>", "user", "pwd");

DirectorySearcher searcher = new DirectorySearcher(groupEntry);
searcher.SearchScope = SearchScope.Base;
searcher.AttributeScopeQuery = "member";
searcher.Filter = "(&(objectCategory=person)(objectClass=user))";
searcher.PropertiesToLoad.Clear();
searcher.PropertiesToLoad.Add("name");
searcher.PropertiesToLoad.Add("mail");
searcher.PropertiesToLoad.Add("displayName");

foreach (SearchResult result in searcher.FindAll())
{
    Console.WriteLine(result.Path);
}

对于嵌套组成员,您可以使用 LDAP_MATCHING_RULE_IN_CHAIN 匹配规则。这需要 2008 R2 的域/林功能级别(同样,忘记域或林)。

DirectoryEntry rootEntry = new DirectoryEntry("GC://<server>", "user", "pwd");

DirectorySearcher searcher = new DirectorySearcher(rootEntry);
searcher.SearchScope = SearchScope.Subtree;
searcher.Filter = "(&(objectCategory=person)(objectClass=user)(memberOf:1.2.840.113556.1.4.1941:=<group DN>))";
searcher.PropertiesToLoad.Clear();
searcher.PropertiesToLoad.Add("name");
searcher.PropertiesToLoad.Add("mail");
searcher.PropertiesToLoad.Add("displayName");

foreach (SearchResult result in searcher.FindAll())
{
    Console.WriteLine(result.Path);
}

限制:

  • 两种方法都不处理主要组成员身份
  • ASQ 不能跨域工作,如果找到来自另一个域的成员,则会引发异常。因此,通常您只能对全局组执行此操作。
于 2014-11-15T21:14:12.267 回答
0

您可以利用 ANR 搜索其中一些属性。有关更多信息,请参阅这篇文章 - 该功能自 2000 年以来一直存在:

http://support.microsoft.com/kb/243299

为了搜索不在默认集中的其他属性,您需要调整架构(这可能不适合您的情况)。

于 2014-01-02T08:53:51.883 回答