Две группы с одинаковым sAMAccountName, использующие FindOne () для получения второго вхождения группы - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть пользователь, который в настоящее время перечисляет "memberOf".Я хотел бы получить некоторые подробности о каждой группе, членом которой является пользователь, такой как обеспечить отличное имя, последнее изменение и описание ... Проблема в том, что я использую 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, я вижу, что одноименное имя показывает DC = office для одной группы, хотя приведенный выше код этого не тянет.

1 Ответ

0 голосов
/ 11 декабря 2018

FindOne() находит только один.Если вам нужно увидеть больше, вам нужно будет использовать FindAll().Просто убедитесь, что вы обернули результат в оператор using, так как в документации говорится, что у вас могут быть утечки памяти, если вы этого не сделаете:

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

Если вы хотите тольконайти 2 (например, если вам нужно только узнать, существует ли более одного), тогда вы можете установить для свойства SizeLimit вашего DirectorySearcher значение 2:

dirSearcher2.SizeLimit = 2;

Примечание об эффективности: когда вы используете .GetDirectoryEntry(), а затем получаете свойства от объекта DirectoryEntry, DirectoryEntry фактически возвращается в AD для получения этих атрибутов, даже если вы уже получили их во время поиска.Вы уже использовали PropertiesToLoad для запроса этих атрибутов, поэтому они уже доступны в вашем SearchResult объекте.Просто имейте в виду, что все атрибуты в Properties списке SearchResult представлены как массивы, поэтому вам всегда нужно использовать [0], даже если они являются однозначными атрибутами в AD.

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

Если также необходимо убедиться, что вы ищете в Глобальном каталоге, который будет возвращать результаты со всех доменов в вашем лесу.Вы делаете это, создавая DirectoryEntry, который вы используете для SearchRoot с GC:// вместо LDAP://.Это говорит о том, что он должен использовать порт 3268 (порт GC), а не порт LDAP по умолчанию (389).Вы создаете этот объект в вашем методе CreateDirectoryEntry().

...