Not able to get the count of Nested Members in AD Group

This topic contains 6 replies, has 3 voices, and was last updated by  amit aman 3 months ago.

  • Author
    Posts
  • #94176

    amit aman
    Participant

    Hi Team,

    I am trying to get the count of the total members of AD Groups in particular OU. These groups contain some nested groups as well. I am not able to get the exact count, in some groups, I am getting a blank, when I checked them individually, I found there are some members present. Also, there are some nested groups as well inside those groups, my code is not able to display them as well. I am pasting the code below, kindly suggest some modification (Don't want to change the whole code :)):

    $a = Get-ADGroup -Filter * | where {$_.distinguishedname -like '*somegroup*'}
    $b = $a.name
    foreach ($ab in $b)
    {
    Get-ADGroupMember $ab| where objectclass -EQ "group" | select name, @{n='Total Members'; e={[string](Get-ADGroupMember -Identity "$_" -Recursive).count}}, @{n='Canonical Name'; e={Get-ADGroup $_ -properties CanonicalName}}
    }

    Thanks,

  • #94251

    Hi

    Following is ugly, but basically does what you need.. 😀

    Function Get-NestedGroup {
        param([string]$name)
        [PSCustomObject]@{
            Parent = $name
            Child = $null
            ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
        }
        $Parent = $name
        Get-ADGroup -Identity $name | Get-ADGroupMember | where {$_.objectClass -eq 'Group'} | ForEach {
            
            $name = $_.name
            If (Get-ADGroup -Identity $name | Get-ADGroupMember | where {$_.objectClass -eq 'Group'}) {
            Get-NestedGroup -name $name
    
            #if group does have groups
            [PSCustomObject]@{
                Parent = $Parent
                Child = $name
                ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
            }
    
            } Else {
            #if group does not have groups
            [PSCustomObject]@{
                Parent = $Parent
                Child = $name
                ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
            }
            }
        }
    }
    
    Get-NestedGroup -name 'group1' | Sort Parent
    

    Output is following:

    Parent Child  ChildGroupCount
    ------ -----  ---------------
    group1                      2
    group1 Group3               1
    group1 Group2               0
    Group3                      1
    Group3 Group4               1
    Group4                      1
    Group4 Group5               0
    

    Regards

    Jake

  • #94254

    Hi

    Basicly this does what you need, not pretty but..

    
    $global:collection = New-Object System.Collections.Generic.List[System.Object]
    
    Function Get-NestedGroup {
    
        param([string]$name)
    
        $collection.add([PSCustomObject]@{
            Parent = $name
            Child = $null
            ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
        })
    
        $Parent = $name
    
        Get-ADGroup -Identity $name | Get-ADGroupMember | where {$_.objectClass -eq 'Group'} | ForEach {
            
            $name = $_.name
    
            $collection.add([PSCustomObject]@{
                Parent = $Parent
                Child = $name
                ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
            })
    
            If ($Global:collection.Parent -match $name) {continue}
    
            Get-NestedGroup -name $name
            
        }
    }
    
    Get-NestedGroup -name 'group1'
    $global:collection | sort parent
    
    

    Output is following:

    Parent Child  ChildGroupCount
    ------ -----  ---------------
    group1                      2
    group1 Group3               1
    group1 Group2               0
    Group2                      0
    Group3                      1
    Group3 Group4               1
    Group4                      1
    Group4 Group5               1
    Group5                      1
    Group5 Group1               2
    

    edit. This becomes perpetual motion machine when Group1 was member of Group5. So not working as it should.
    edit2. Thanks to Aapeli Hietikko for pointing the $global:collection. Manager to resolve the perpetual motion machine and it skips if the child group is already found as parent.

    Regards

    Jake

  • #94261

    Hi

    Basicly this does what you need, not pretty but..

    
    $global:collection = New-Object System.Collections.Generic.List[System.Object]
    
    Function Get-NestedGroup {
    
        param([string]$name)
    
        $collection.add([PSCustomObject]@{
            Parent = $name
            Child = $null
            ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
        })
    
        $Parent = $name
    
        Get-ADGroup -Identity $name | Get-ADGroupMember | where {$_.objectClass -eq 'Group'} | ForEach {
            
            $name = $_.name
    
            $collection.add([PSCustomObject]@{
                Parent = $Parent
                Child = $name
                ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
            })
    
            If ($Global:collection.Parent -match $name) {continue}
    
            Get-NestedGroup -name $name
            
        }
    }
    
    Get-NestedGroup -name 'group1'
    $global:collection | sort parent
    
    

    Output is following:

    Parent Child  ChildGroupCount
    ------ -----  ---------------
    group1                      2
    group1 Group3               1
    group1 Group2               0
    Group2                      0
    Group3                      1
    Group3 Group4               1
    Group4                      1
    Group4 Group5               1
    Group5                      1
    Group5 Group1               2
    

    edit. This becomes perpetual motion machine when Group1 was member of Group5. So not working as it should.
    edit2. Thanks to Aapeli Hietikko for pointing the $global:collection. Manager to resolve the perpetual motion machine and it skips if the child group is already found as parent.
    edit3. Seems like I have modified this too many times, sorry admins!

    Regards

    Jake

    • #94264

      Hi

      Forgot the canonical name, so here you go.

      $global:collection = New-Object System.Collections.Generic.List[System.Object]
      
      Function Get-NestedGroup {
      
          param([string]$name)
      
          $collection.add([PSCustomObject]@{
              Parent = $name
              Child = $null
              ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
              "Canonical Name" = (Get-ADGroup $name -properties CanonicalName).canonicalname
          })
      
          $Parent = $name
      
          Get-ADGroup -Identity $name | Get-ADGroupMember | where {$_.objectClass -eq 'Group'} | ForEach {
              
              $name = $_.name
      
              $collection.add([PSCustomObject]@{
                  Parent = $Parent
                  Child = $name
                  ChildGroupCount = Get-ADGroupMember -Identity $name | measure | select -ExpandProperty count
                  "Canonical Name" = (Get-ADGroup $name -properties CanonicalName).canonicalname
              })
      
              If ($Global:collection.Parent -match $name) {continue}
      
              Get-NestedGroup -name $name
              
          }
      }
      
      Get-NestedGroup -name 'group1'
      $global:collection | sort parent
      
      

      Regards

      Jake

    • #94332

      amit aman
      Participant

      this is what I was looking for. Thanks a ton mate. You were such a sport. 🙂

  • #94305

    postanote
    Participant

    There are lots of examples, some fully built that handle this exact use case. Here are a few from my OneNote library have had for a few years on this topic.

    Token Bloat Troubleshooting by Analyzing Group Nesting in AD

    This tool started when I was finding ways to analyze the complexity of group memberships in AD. Other than the usual average/median/min/max of number of members, number of memberships etc, I was also interested in finding out the maximum nesting levels of groups and the recursive group membership count. For e.g. in the diagram below, the maximum nesting level of 'group a' is 3 and its recursive group membership count is 6.

    'blogs.msdn.microsoft.com/adpowershell/2009/09/04/token-bloat-troubleshooting-by-analyzing-group-nesting-in-ad'

    Get nested group membership – function
    This function will recursively enumerate members of a given group along with nesting level and parent group information. If there is a circular membership, it will be displayed in Comment column.It accepts input from pipeline and works well with get-adgroup.

    'gallery.technet.microsoft.com/scriptcenter/Get-nested-group-15f725f2'

    How To Find Nested Active Directory Group Memberships in PowerShell

    'redmondmag.com/articles/2016/03/15/nested-active-directory-group-memberships.aspx'

    Get AD Nested Group Members with Powershell
    This article helps you to query nested AD group members using powershell. We can get group members by using the Active Directory powershell cmlet Get-ADGroupMember. The Get-ADGroupMember cmdlet provides the option to get all the nested group members by passing the parameter -Recursive. This powershell script also handles circular membership (infinite loop) problem.
    'morgantechspace.com/2015/09/get-ad-nested-group-members-with-powershell.html'

    How to find and report nested groups in Active Directory using PowerShell

    'vhomelab.com/2014/10/04/how-to-find-and-report-nested-groups-in-active-directory-using-powershell'

    PowerShell Problem Solver: Enumerating Members of Large Active Directory Groups

    'petri.com/enumerating-members-of-large-active-directory-groups'

You must be logged in to reply to this topic.