具有相同 sAMAccountName 的两个组,使用 FindOne() 获取组的第二次出现

Two Groups with the same sAMAccountName, using FindOne() to getting the second occurance of group

我目前正在列出一个用户 "memberOf"。我想获得有关用户所属的每个组的一些详细信息,例如 distinguishedName、上次修改时间和描述...问题是,我在我的代码中使用 FindOne() 并且我有几个组与 sAMAccountName在各个域中重复。有没有一种方法可以使用 FindOne() 并获得该组的第二次出现,因为我在下面进行了编码,或者我是否需要重写并使用 FindAll() 并以这种方式处理它。 相关代码如下:

foreach (object item in groups)
            {
                string groupProp = string.Empty;
                using (DirectoryEntry dirEntry = CreateDirectoryEntry())
                {
                    using (DirectorySearcher dirSearcher2 = new DirectorySearcher(dirEntry))
                    {
                        dirSearcher2.Filter = string.Format("(sAMAccountName=" + item + ")");
                        dirSearcher2.PropertiesToLoad.Add("description");
                        dirSearcher2.PropertiesToLoad.Add("whenChanged");
                        dirSearcher2.PropertiesToLoad.Add("distinguishedName");

                        SearchResult searchResult2 = dirSearcher2.FindOne();

                        if (searchResult2 != null)
                        {
                            DirectoryEntry employee = searchResult2.GetDirectoryEntry();
                            string desc = string.Empty;
                            string date = string.Empty;
                            string dname = string.Empty;
                            if (employee.Properties["description"].Value != null)
                            {
                                desc = employee.Properties["description"].Value.ToString();
                            }
                            if (employee.Properties["whenChanged"].Value != null)
                            {
                                date = employee.Properties["whenChanged"].Value.ToString();
                            }
                            if (employee.Properties["distinguishedName"].Value != null)
                            {
                                dname = employee.Properties["distinguishedName"].Value.ToString();
                                if (dname.Contains("DC=academic"))
                                {
                                    dname = "academic";
                                }
                            }
                        }
                }
            }

相关新代码:

using (var results = dirSearcher2.FindAll())
                        {
                            foreach (SearchResult searchResult2 in results)
                            {
                                html.Append("<tr><td>" + item.ToString() + "</td>");
                                if (searchResult2.Properties.Contains("description"))
                                {
                                    desc = searchResult2.Properties["description"][0].ToString();
                                }
                                if (searchResult2.Properties.Contains("whenChanged"))
                                {
                                    date = searchResult2.Properties["whenChanged"][0].ToString();
                                }
                                if (searchResult2.Properties.Contains("distinguishedName"))
                                {
                                    dom = searchResult2.Properties["distinguishedName"][0].ToString();
                                    if (dom.Contains("DC=academic"))
                                    {
                                        dname = "academic";
                                    }
                                    else if (dom.Contains("DC=office"))
                                    {
                                        dname = "office";
                                    }
                                    else
                                    {
                                        dname = "not listed";
                                    }
                                }
                                html.Append("<td>" + desc + "</td><td>" + dname + "</td><td>" + date + "</td></tr>");
                            }

基本上,我得到的结果与我的第一个代码得到的结果相同,IE 没有得到关于第二组的正确信息。 IE:我有两个名为 AppDev 的组,它们都在不同的域中;但是,两者都显示出学术性。当我查看 AD 时,我看到 distiguished 名称在一组上显示 DC=office,尽管上面的代码没有提取它。

FindOne()只找到一个。如果您需要查看更多内容,则需要使用 FindAll()。只需确保将结果包装在 using 语句中,因为 documentation 表示如果不这样做,可能会发生内存泄漏:

using (var results = dirSearcher2.FindAll()) {
    foreach (SearchResult searchResult2 in results) {
        //do stuff
    }
}

如果你只想找到2个(比如你只需要知道是否存在多个),那么你可以设置你的DirectorySearcherSizeLimit 属性 ] 到 2:

dirSearcher2.SizeLimit = 2;

关于效率的注意事项:当您使用 .GetDirectoryEntry() 然后从 DirectoryEntry 对象获取属性时,DirectoryEntry 实际上返回到 AD 获取这些属性,即使您在搜索过程中已经找到了它们。您已经使用 PropertiesToLoad 请求这些属性,因此它们在您的 SearchResult 对象中已经可用。请注意 SearchResultProperties 列表中的所有属性都以数组形式呈现,因此您始终需要使用 [0],即使它们在 AD 中是单值属性。

if (searchResult2.Properties.Contains("description")) {
    desc = searchResult2.Properties["description"][0];
}

如果还需要确保您正在搜索全局目录,它将 return 来自您林中所有域的结果。为此,您可以使用 GC:// 而不是 LDAP:// 创建用于 SearchRootDirectoryEntry。这告诉它使用端口 3268(GC 端口)而不是默认的 LDAP 端口 (389)。您正在 CreateDirectoryEntry() 方法中创建此对象。