Получить список пользователей из Active Directory в данной группе AD

У меня есть код, который ищет всех пользователей в отделе:

string Department = "Billing";
DirectorySearcher LdapSearcher = new DirectorySearcher();
LdapSearcher.PropertiesToLoad.Add("displayName");
LdapSearcher.PropertiesToLoad.Add("cn");
LdapSearcher.PropertiesToLoad.Add("department");
LdapSearcher.PropertiesToLoad.Add("title");
LdapSearcher.PropertiesToLoad.Add("memberOf");
LdapSearcher.Filter = string.Format("(&(objectClass=user)(department={0}))", Department);
SearchResultCollection src = LdapSearcher.FindAll();

Как бы выглядел фильтр, если бы я хотел, чтобы все входили в группу AD "Только для чтения"?

Я все об этом ошибаюсь?

5 ответов

Решение

Глядя на ваш поиск, у меня есть пара моментов для вас. Во-первых, поиск использует objectClass (не индексируется) вместо objectCategory (индексируется). Огромная проблема производительности с этим запросом. Вы бы всегда хотели объединить их вместе в зависимости от того, что вы пытаетесь получить:

(&(objectCategory=person)(objectClass=user)) = All users (no contacts)
(&(objectCategory=person)(objectClass=contact)) = All contacts (no users)
(&(objectCategory=person)) = All users and contacts

Что касается поиска пользователей в группе, вы можете перечислить список объектов-членов определенной группы. В атрибуте member объекта group находится однозначное имя каждого пользователя.

Эта статья описывает перечисление членов группы...

Не забывайте, что вам, возможно, придется обрабатывать вложенные группы родительской группы, так как нет способа по умолчанию обрабатывать это с помощью запросов LDAP. Для этого вам может потребоваться оценить, является ли объект-член группой, а затем получить атрибут участника для этой дочерней группы.

Наконец, вы должны привыкнуть указывать префикс dns в своем запросе.

Без префикса DNS:

LDAP://ou=ouname,dc=domain,dc=com

С префиксом DNS (все три работают):

LDAP://servername/ou=ouname,dc=domain,dc=com
LDAP://servername.domain.com/ou=ouname,dc=domain,dc=com
LDAP://domain.com/ou=ouname,dc=domain,dc=com

Один домен не вызовет особых проблем, но когда вы попробуете выполнить поиск в среде с несколькими доменами, вы не получите этого дополнения. Надеюсь, это поможет вам приблизиться к вашей цели.

Я всегда находил Howto: (почти) все в Active Directory через C# помогает в большинстве вопросов AD.

Если вы уже знаете путь AD к группе, вероятно, было бы проще открыть на нем объект DirectoryEntry, а затем выполнить DirectorySearcher оттуда.

using (DirectoryEntry de = new DirectoryEntry("LDAP://somedomain/CN=FooBar"))
{
   DirectorySearcher search = new DirectorySearcher(de, ("(objectClass=user)"));
}

Также в поисковике есть флаг для того, чтобы детализировать до субконтейнеров, я забыл название от руки.

Я использую следующий код (от http://blogs.technet.com/b/brad_rutkowski/archive/2008/04/15/c-getting-members-of-a-group-the-easy-way-with-net-3-5-discussion-groups-nested-recursive-security-groups-etc.aspx) это работает отлично.

IList<string> getMembers(string domainName, string groupName)
    {
        PrincipalContext ctx = new PrincipalContext(ContextType.Domain, domainName);
        GroupPrincipal grp = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, groupName);

        if (grp == null) { 
            throw new ApplicationException("We did not find that group in that domain, perhaps the group resides in a different domain?");
        }

        IList<string> members = new List<String>();

        foreach (Principal p in grp.GetMembers(true))
        {
            members.Add(p.Name); //You can add more attributes, samaccountname, UPN, DN, object type, etc... 
        }
        grp.Dispose();
        ctx.Dispose();

        return members;
    }
    //Search for Group and list group members

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.DirectoryServices.AccountManagement;

namespace ExportActiveDirectoryGroupsUsers
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args == null)
            {
                Console.WriteLine("args is null, useage: ExportActiveDirectoryGroupsUsers OutputPath"); // Check for null array
            }
            else
            {
                Console.Write("args length is ");
                Console.WriteLine(args.Length); // Write array length
                for (int i = 0; i < args.Length; i++) // Loop through array
                {
                    string argument = args[i];
                    Console.Write("args index ");
                    Console.Write(i); // Write index
                    Console.Write(" is [");
                    Console.Write(argument); // Write string
                    Console.WriteLine("]");
                }
                try
                {
                    using (var ServerContext = new PrincipalContext(ContextType.Domain, ServerAddress, Username, Password))
                    {
                        /// define a "query-by-example" principal - here, we search for a GroupPrincipal 
                        GroupPrincipal qbeGroup = new GroupPrincipal(ServerContext, args[0]);

                        // create your principal searcher passing in the QBE principal    
                        PrincipalSearcher srch = new PrincipalSearcher(qbeGroup);

                        // find all matches
                        foreach (var found in srch.FindAll())
                        {
                            GroupPrincipal foundGroup = found as GroupPrincipal;

                            if (foundGroup != null)
                            {
                                // iterate over members
                                foreach (Principal p in foundGroup.GetMembers())
                                {
                                    Console.WriteLine("{0}|{1}", foundGroup.Name, p.DisplayName);
                                    // do whatever you need to do to those members
                                }
                            }

                        }
                    }
                    //Console.WriteLine("end");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Something wrong happened in the AD Query module: " + ex.ToString());
                }
                Console.ReadLine();
            }
        }
    }
}
Другие вопросы по тегам