none
List nested groups RRS feed

  • Question

  • I do find a lot of scripts to list the members of specific Active Directory groups. But i don't want to specify a group.

    I'm looking for a script to report all Active Directory groups with nested groups, and the nested group members. Not the user accounts in the nested groups, only the groups within the groups, within the (sub) groups etc.

    Thanks

    Sunday, March 20, 2016 9:03 AM

Answers

  • There is no filter possible for checking the class of group members, so each member of each group must be evaluated. The following PowerShell script should get you started:

    $Groups = Get-ADGroup -LDAPFilter "(member=*)"
    ForEach ($Group In $Groups)
    {
        $DN = $Group.distinguishedName
        $Members = Get-ADGroupMember -Identity $DN
        $Nested = $False
        ForEach ($Member In $Members)
        {
            If ($Member.objectClass -eq "group")
            {
                If ($Nested -eq $False)
                {
                    $Nested = $True
                    "Group: $DN"
                }
                "    Nested Group: " + $Member.distinguishedName
            }
        }
    }
    


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Biga_b Sunday, March 20, 2016 8:11 PM
    Sunday, March 20, 2016 1:14 PM
  • That is a bit more advanced. I always need to look up how to do it.

    In the script I posted before I used the variable $Nested to ensure that the DN of the parent group was output only once, then all of the group members output indented below. For a csv file, each entry should include both the parent group and the members that are groups. The variable $Nested is not needed. This solution worked in my tests:

    # Define array for results to be exported.
    $Results = @()
    
    # Retrieve all groups with at least one member.
    $Groups = Get-ADGroup -LDAPFilter "(member=*)"
    
    ForEach ($Group In $Groups)
    {
        $DN = $Group.distinguishedName
        # Retrieve all direct members of the group.
        $Members = Get-ADGroupMember -Identity $DN
        ForEach ($Member In $Members)
        {
            # Consider only nested groups.
            If ($Member.objectClass -eq "group")
            {
                # Add the parent group and the group member to the array.
                # Each element of the array is a hash table with one name-value pair.
                $Results += New-Object -Type PSObject -Property (
                    @{
                        "Name" = $DN
                        "Nested Group" = $Member.distinguishedName
                    }
                )
            }
        }
    }
    # Export the array to the specified CSV file.
    $Results | Export-Csv -Path "c:\NestedGroups.csv" -NoTypeInformation
    
    Since we have references to both the parent group object, and the group members, we can document any attributes of each that we want. For example, you could replace distinguishedName with sAMAccountName in the two places in this script. Or, you could even document the Name of the objects (although that might not uniquely identify the objects).

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Biga_b Tuesday, March 22, 2016 7:38 AM
    Sunday, March 20, 2016 10:31 PM

All replies

  • There is no filter possible for checking the class of group members, so each member of each group must be evaluated. The following PowerShell script should get you started:

    $Groups = Get-ADGroup -LDAPFilter "(member=*)"
    ForEach ($Group In $Groups)
    {
        $DN = $Group.distinguishedName
        $Members = Get-ADGroupMember -Identity $DN
        $Nested = $False
        ForEach ($Member In $Members)
        {
            If ($Member.objectClass -eq "group")
            {
                If ($Nested -eq $False)
                {
                    $Nested = $True
                    "Group: $DN"
                }
                "    Nested Group: " + $Member.distinguishedName
            }
        }
    }
    


    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Biga_b Sunday, March 20, 2016 8:11 PM
    Sunday, March 20, 2016 1:14 PM
  • Thank you very much Richard. This definitely will get me started. 

    Can i export this to a CSV file. I think i have to insert something like 

    Export-CSV -Path $File -NoTypeInformation -Encoding UTF8 

    at the end of the script, but i can't get it to work. My powershell skills are bad. I can sometimes modify a script a little bit, but that's it. 

    Thanks

    Sunday, March 20, 2016 8:10 PM
  • That is a bit more advanced. I always need to look up how to do it.

    In the script I posted before I used the variable $Nested to ensure that the DN of the parent group was output only once, then all of the group members output indented below. For a csv file, each entry should include both the parent group and the members that are groups. The variable $Nested is not needed. This solution worked in my tests:

    # Define array for results to be exported.
    $Results = @()
    
    # Retrieve all groups with at least one member.
    $Groups = Get-ADGroup -LDAPFilter "(member=*)"
    
    ForEach ($Group In $Groups)
    {
        $DN = $Group.distinguishedName
        # Retrieve all direct members of the group.
        $Members = Get-ADGroupMember -Identity $DN
        ForEach ($Member In $Members)
        {
            # Consider only nested groups.
            If ($Member.objectClass -eq "group")
            {
                # Add the parent group and the group member to the array.
                # Each element of the array is a hash table with one name-value pair.
                $Results += New-Object -Type PSObject -Property (
                    @{
                        "Name" = $DN
                        "Nested Group" = $Member.distinguishedName
                    }
                )
            }
        }
    }
    # Export the array to the specified CSV file.
    $Results | Export-Csv -Path "c:\NestedGroups.csv" -NoTypeInformation
    
    Since we have references to both the parent group object, and the group members, we can document any attributes of each that we want. For example, you could replace distinguishedName with sAMAccountName in the two places in this script. Or, you could even document the Name of the objects (although that might not uniquely identify the objects).

    Richard Mueller - MVP Enterprise Mobility (Identity and Access)

    • Marked as answer by Biga_b Tuesday, March 22, 2016 7:38 AM
    Sunday, March 20, 2016 10:31 PM
  •  In my little test environment the scripts works, but in live i get the following error:

    Get-ADGroupMember : There is no such object on the server
    At line:11 char:16
    +     $Members = Get-ADGroupMember -Identity $DN
    +                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ObjectNotFound: (CN=Exchange FUL...C=Domain,DC=int:ADGroup) [Get-ADGroupMember], ADIdentityNotFoundException
        + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADGroupMember

    Thanks

    Monday, March 21, 2016 10:36 PM
  • Never mind the error. I think deleted account SID is the problem. 

    Thanks man. 

    Because of a future Active Directory migration i have to generate some reports about our AD structure. Also reports for permissions on shares, files and folders. If you got the time, maybe you can help me with my other thread.

    https://social.technet.microsoft.com/Forums/windowsserver/en-US/68f27825-6cce-442e-a9e4-70f9acbbec79/list-all-permission-of-all-users-and-group-membership-in-a-domain?forum=winserversecurity

    Thanks

    Monday, March 21, 2016 11:11 PM