locked
Nested Queries on AD group membership - what groups do groups belong to RRS feed

  • Question

  • User369345748 posted

    I am using a .NET 46 MVC app to query an AD Group structure that reflects an organisation :  

    Contoso Global

        -Contoso Asia

             + Contoso China
               etc.....
        -Contoso Europe
              - Contoso UK
              +Contoso Birmingham
                                        etc.
              -Contoso London
                      Ian Jones  - the boss in London
                      +Contoso UK HR
                               etc.
                      - Contoso UK Finance
                                        Fred Blogs
                                        Helen Brown

    Each AD Group is made up of both people ( EG Managers ) and other 'child' AD groups

    In the example above, 'Contoso London' would include 

    • Contoso UK Finance
    • Contoso UK HR
    • Ian Jones 

    I can find out all the groups that 'Helen Brown' belongs to both directly and via nested groups. 

    How do I take a group as the start point, using .NET Framework 4.6C # .  to find out the groups it belongs to, and the groups and members who belong to

    I suspect this will be two distinct queries to find out

    a) What groups and people belong to 'Contoso London' ( desired answer : Contoso UK HR, Contoso UK Finance,  Ian Jones, Fred Blogs,Helen Brown) ?

    b) What groups is 'Contoso London' a member of  (desired answer : Contoso global, Contoso Europe, Contoso UK) ?

    Any ideas gratefully received. 

    Thanks , Richard

    Thursday, October 17, 2019 6:01 AM

All replies

  • User1724605321 posted

    Hi Richard ,

    There are  a lot of code samples for how to recursively query group membership available , please refer to below links for code samples :

    https://stackoverflow.com/a/3668183/5751404

    https://stackoverflow.com/questions/7826927/recursively-querying-ldap-group-membership

    https://stackoverflow.com/questions/6252819/find-recursive-group-membership-active-directory-using-c-sharp

    Hope that helps.

    Best Regards,

    Nan Yu

    Friday, October 18, 2019 2:40 AM
  • User369345748 posted

    Thank you for the reply 

    I have built the following functions, which I post below to help anyone else who might have the issue 

    public static List<string> GetAllGroupMembers(string groupName, string domainName = null)        {
                var result = new List<string>();
                if (groupName == "")
                    return result;
                if (groupName.Contains('\\') || groupName.Contains('/'))
                {
                    domainName = groupName.Split(new char[] { '\\', '/' })[0];
                    groupName = groupName.Split(new char[] { '\\', '/' })[1];
                }
                try
                {
                    PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
                    GroupPrincipal myGroup = GroupPrincipal.FindByIdentity(ctx, groupName);
                    var memberList = myGroup.GetMembers();
                    foreach (Principal p in memberList)
                    {
                        UserPrincipal theUser = p as UserPrincipal;
                        if (theUser != null)
                        {
                            result.Add(theUser.Name  +"| UserID");
                        }
                        GroupPrincipal theGroup = p as GroupPrincipal;
                        if (theGroup != null)
                        {
                            result.Add(theGroup.Name + "| Group");
                            result.AddRange(GetAllGroupMembers(theGroup.Name));
                        }
                    }
                    }
                catch (Exception ex)
                {
     // Error process
                } 
                return result;
            }
     
     
            private static List<string> GetGroupsBelongedTo(string groupName, string domainName = null)
            {
                var result = new List<string>();
                if (groupName == "")
                    return result;
                if (groupName.Contains('\\') || groupName.Contains('/'))
                {
                    domainName = groupName.Split(new char[] { '\\', '/' })[0];
                    groupName = groupName.Split(new char[] { '\\', '/' })[1];
                }
                try
                {
                    PrincipalContext ctx = new PrincipalContext(ContextType.Domain);
                    GroupPrincipal myGroup = GroupPrincipal.FindByIdentity(ctx, groupName);
                    var memberList = myGroup.GetGroups();
                    foreach (Principal p in memberList)
                    {
                       UserPrincipal theUser = p as UserPrincipal;
                        if (theUser != null)
                        {
                            result.Add(theUser.Name + "| UserID");
                        }
                        GroupPrincipal theGroup = p as GroupPrincipal;
                        if (theGroup != null)
                        {
                            result.Add(theGroup.Name + "| Group");
                            result.AddRange(GetGroupsBelongedTo(theGroup.Name));
                        }
                    }
                }
                catch (Exception ex)
                {
                     // Error process
                }         
                return result;
            }

    These are called as follows 

    var groupsb = GetAllGroupMembers(item);
    //get the users out beneath this in the tree
    var groupsb1 = from element in groupsb where element.Contains("| UserID") orderby element select element.Replace("| UserID","");
     
    //get the groups out beneath this in the tree
    var groupsb2 = from element in groupsb where element.Contains("| Group") orderby element select element.Replace("| Group", "");
     
    // Get groups out above this in the tree

    var groupsC = GetGroupsBelongedTo(item);
     var groupsc1 = from element in groupsC  orderby element select element.Replace("| Group", "");
     

     
     

    Friday, October 18, 2019 9:31 AM