【问题标题】:get all users from a group in Active Directory从 Active Directory 中的组中获取所有用户
【发布时间】:2011-10-27 11:21:07
【问题描述】:

我试图在 AD 中获取特定组的所有用户,然后返回映射到我的 Employee 类中的属性的员工列表。我有:

我的过滤器没有产生任何结果 - 它应该是什么?

另外,我在这里尝试了第一个解决方案: List of users in specific Active Directory Distribution Group,但我需要使用该方法无法获得的详细信息,例如移动设备、扩展程序等。

public static List<Employee> CreateEmployeeList(string department)
{
    List<Employee> employees = new List<Employee>();
    string filter = string.Format("(&(ObjectClass=person)(memberOf=CN={0},OU=Users & Groups,OU=Blah,DC=Blah,DC=Blah,DC=Blah))", department);

    DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.Secure);
    DirectorySearcher searcher = new DirectorySearcher(adRoot);
    searcher.SearchScope = SearchScope.Subtree;
    searcher.ReferralChasing = ReferralChasingOption.All;
    searcher.Filter = filter;
    SearchResultCollection results = searcher.FindAll();

    foreach (SearchResult user in results)
    {
        // do whatever you need to do with the entry

        if (user != null)
        {
            UserDirectoryEntry = user.GetDirectoryEntry();
            string displayName = GetUserProperty("displayName");
            string firstName = GetUserProperty("givenName");
            string lastName = GetUserProperty("sn");
            string email = GetUserProperty("mail");
            string tel = GetUserProperty("telephonenumber");
            string extension = GetUserProperty("ipphone");
            string mobile = GetUserProperty("mobile");
            string title = GetUserProperty("description");
            employees.Add(new Employee{ FullName = displayName, FirstName = firstName, Surname = lastName, Email = email.ToLower(), Telephone = tel, Extension = extension, Mobile = mobile, JobTitle = title });
        }
    }
    return employees;
}

【问题讨论】:

    标签: c# .net active-directory


    【解决方案1】:
    using (var context = new PrincipalContext(ContextType.Domain, "domainName"))
    {
        using (var group = GroupPrincipal.FindByIdentity(context, "groupName"))
        {
            if (group == null)
            {
                MessageBox.Show("Group does not exist");
            }
            else
            {
                var users = group.GetMembers(true);
                foreach (UserPrincipal user in users)
                {
                     //user variable has the details about the user 
                }
            } 
        }
    }
    

    【讨论】:

    • 完美解决方案,谢谢!顺便提一句。 .NET Framework 4.5 中无需添加“域名”
    • 需要引用 System.DirectoryServices.AccountManagement。
    • 不幸的是,这只会返回用户对象的组成员,而不会返回联系人对象的组成员。有没有办法返回所有组成员?
    • 另外,成员可以是用户OR GROUPS。如果 var "users" 包含一个组,这不会抛出异常吗?
    • @StefanSteiger :GetMembers() 中的true 标志指定recursive search,因此不会引发错误。
    【解决方案2】:

    这应该返回一个组中的所有 Active Directory 用户。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.DirectoryServices;
    
    namespace ADQuery
    {
        class Program
        {
            static void Main(string[] args)
            {
                GetListOfAdUsersByGroup("domain", "group");
                Console.ReadLine();
            }
    
            public static void GetListOfAdUsersByGroup(string domainName, string groupName)
            {
                DirectoryEntry entry = new DirectoryEntry("LDAP://DC=" + domainName + ",DC=com");
                DirectorySearcher search = new DirectorySearcher(entry);
                string query = "(&(objectCategory=person)(objectClass=user)(memberOf=*))";
                search.Filter = query;
                search.PropertiesToLoad.Add("memberOf");
                search.PropertiesToLoad.Add("name");
    
                System.DirectoryServices.SearchResultCollection mySearchResultColl = search.FindAll();
                Console.WriteLine("Members of the {0} Group in the {1} Domain", groupName, domainName);
                foreach (SearchResult result in mySearchResultColl)
                {
                    foreach (string prop in result.Properties["memberOf"])
                    {
                        if (prop.Contains(groupName))
                        {
                            Console.WriteLine("    " + result.Properties["name"][0].ToString());
                        }
                    }
                }
            }
        }
    }
    

    祝你好运!

    【讨论】:

    • 不确定是什么 (!(userAccountControl:1.2.840.113556.1.4.803:=2))(&(mail=*) 的意思是 - 我也需要按组过滤
    • 对不起,我太着急了,把你的问题读错了,我贴了一些应该更有帮助的代码。
    【解决方案3】:

    以下代码将递归搜索嵌套的域本地组和/或全局组以查找用户。您可以对其进行修改以查看任何组的顺序以满足您的需要或返回您想要的任何类型的组。

    // Set the list to return and get the group we are looking through.
    List<UserPrincipal> list = new List<UserPrincipal>();
    GroupPrincipal group = GroupPrincipal.FindByIdentity(new PrincipalContext(/* connection info here */), ((groupName.Length > 0) ? groupName : this.Properties.Name));
    
    // For each member of the group add all Users.
    foreach (Principal princ in group.Members)
    {
        /*
        To change what you are looking for or how you are looking for it, 
        simply change some of the following conditions to match what you want.
        */
    
        // If this member is a User then add them.
        if (princ.StructuralObjectClass == "user")
        {
            list.Add(UserPrincipal.FindByIdentity(new PrincipalContext(/* connection info here */), princ.Name);
        }
    
        // If we are looking recursively and this member is a GL_Group then get the Users in it and add them.
        if (recursive && (princ.StructuralObjectClass == "group") && (((GroupPrincipal)princ).GroupScope == GroupScope.Global))
        {
            list.AddRange(this.GetUsers(true, princ.Name));
        }
    }
    return list;
    

    【讨论】:

      【解决方案4】:

      the example by Dalton 为基础,下面是获取组用户名的简洁代码:

      static SortedSet<string> GetUsernames(string domainName, string groupName) {
        using (var pc = new PrincipalContext(ContextType.Domain, domainName))
        using (var gp = GroupPrincipal.FindByIdentity(pc, groupName))
          return gp == null ? null : new SortedSet<string>(
            gp.GetMembers(true).Select(u => u.SamAccountName));
      }
      

      【讨论】:

        【解决方案5】:

        In this post 我在 ActiveDirectory 2003 和 2008 R2 中写了一些东西。我使用微软LDAP_MATCHING_RULE_IN_CHAIN。该服务使用 DirectoryServices。这段代码要小心,因为有双重搜索。

        但您也可以使用Managing Directory Security Principals in the .NET Framework 3.5 来完成。你可以阅读this other post。您必须获得 GroupPrincipal 并且您正在寻找 Members 属性。它还存在于 StackOverflow 中的其他条目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多