Get members of an Active Directory group recursively, i.e. including subgroups

前端 未结 2 603
小鲜肉
小鲜肉 2020-12-30 11:49

Given a group like this in Active Directory:

MainGroup
  GroupA
    User1
    User2
  GroupB
    User3
  User4

I can easily determine if Us

2条回答
  •  孤城傲影
    2020-12-30 12:49

    Just in case this might benefit someone else: here is the solution I ended up with. It is just a recursive search, with some extra checks to avoid checking the same group or user twice, e.g. if groupA is member of groupB and groupB is member of groupA or a user is member of more than one group.

    using System;
    using System.DirectoryServices;
    using System.Collections.Generic;
    
    static class Program {
    
        static IEnumerable GetMembers(DirectoryEntry searchRoot, string groupDn, string objectClass) {
            using (DirectorySearcher searcher = new DirectorySearcher(searchRoot)) {
                searcher.Filter = "(&(objectClass=" + objectClass + ")(memberOf=" + groupDn + "))";
                searcher.PropertiesToLoad.Clear();
                searcher.PropertiesToLoad.AddRange(new string[] { 
                    "objectGUID",
                    "sAMAccountName",
                    "distinguishedName"});
                searcher.Sort = new SortOption("sAMAccountName", SortDirection.Ascending);
                searcher.PageSize = 1000;
                searcher.SizeLimit = 0;
                foreach (SearchResult result in searcher.FindAll()) {
                    yield return result;
                }
            }
        }
    
        static IEnumerable GetUsersRecursively(DirectoryEntry searchRoot, string groupDn) {
            List searchedGroups = new List();
            List searchedUsers = new List();
            return GetUsersRecursively(searchRoot, groupDn, searchedGroups, searchedUsers);
        }
    
        static IEnumerable GetUsersRecursively(
            DirectoryEntry searchRoot,
            string groupDn,
            List searchedGroups,
            List searchedUsers) {
            foreach (var subGroup in GetMembers(searchRoot, groupDn, "group")) {
                string subGroupName = ((string)subGroup.Properties["sAMAccountName"][0]).ToUpperInvariant();
                if (searchedGroups.Contains(subGroupName)) {
                    continue;
                }
                searchedGroups.Add(subGroupName);
                string subGroupDn = ((string)subGroup.Properties["distinguishedName"][0]);
                foreach (var user in GetUsersRecursively(searchRoot, subGroupDn, searchedGroups, searchedUsers)) {
                    yield return user;
                }
            }
            foreach (var user in GetMembers(searchRoot, groupDn, "user")) {
                string userName = ((string)user.Properties["sAMAccountName"][0]).ToUpperInvariant();
                if (searchedUsers.Contains(userName)) {
                    continue;
                }
                searchedUsers.Add(userName);
                yield return user;
            }
        }
    
        static void Main(string[] args) {
            using (DirectoryEntry searchRoot = new DirectoryEntry("LDAP://DC=x,DC=y")) {
                foreach (var user in GetUsersRecursively(searchRoot, "CN=MainGroup,DC=x,DC=y")) {
                    Console.WriteLine((string)user.Properties["sAMAccountName"][0]);
                }
            }
        }
    
    }
    

提交回复
热议问题