从给定AD组中的Active Directory获取用户列表

时间:2009-02-04 20:23:30

标签: c# active-directory

我有搜索部门中所有用户的代码:

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 个答案:

答案 0 :(得分:34)

看看你的搜索,我有几个要点。首先,搜索使用objectClass(非索引)而不是objectCategory(索引)。该查询存在巨大的性能问题。你总是希望根据你想要检索的内容将两者结合起来:

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

对于查找组中的用户,您可以枚举特定组的成员对象列表。在group对象的member属性中是每个用户的distinguishedName。

This article describes enumerating members of a 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

单个域不会给您带来太多问题,但是当您尝试在多域环境中运行搜索时,如果没有此添加,您将被咬住。希望这有助于使您更接近目标。

答案 1 :(得分:11)

我总是发现Howto: (Almost) Everything In Active Directory via C#有助于解决大多数AD问题。

答案 2 :(得分:6)

如果你知道该组的AD路径,那么打开一个DirectoryEntry可能会更容易,然后从那里做一个DirectorySearcher。

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

Searcher上还有一个标志,表示是否要钻到子容器,我忘了手边的名字。

答案 3 :(得分:3)

我使用以下代码(来自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;
    }

答案 4 :(得分:0)

    //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();
            }
        }
    }
}