Get total number of group membership for specific user

This time I want to show you how to get number of direct and indirect(nested) group membership for specific user.

Please note that once user is a member of about 1000 groups, some SIDs can’t be added to the token. This will cause an access failure when trying to use a resource that requires that token.

As we all know error handling is very important so I added Try/Catch block to our script and mixed it with Do/Until loop. This will ensure us that user name has been provided properly and in case of wrong input it will ask again to provide correct user name.


do{

# Provide username
$username = Read-Host -Prompt "Please provide user ID (e.i 'John.Doe')"
$username = $username.trim() 

    Try 
    { 
         $username = (Get-ADUser -Identity $username)
    }
    Catch 
    {
         Write-Host "Error: " -NoNewline -ForegroundColor Yellow
         Write-Host $_.Exception.Message
         Write-Host " "
         Clear-Variable -Name username
    } 


}until ($username)
 

Next we need to get “Token Groups” for affected user using ADSI query and add results to array. Additionally we can add confirmation step to view all group membership in pop-window.

 
    If($username)
    {
        # ADSI query
        $dn = (Get-ADUser $username).DistinguishedName  
        $ldap = ("LDAP://" + "$dn ")
        $user = [ADSI]"$ldap"
        $user.psbase.refreshCache(@("TokenGroups"))

        $secirc = new-object System.Security.Principal.IdentityReferenceCollection

        ForEach($sidByte in $user.TokenGroups)
        {
            $secirc.Add((new-object System.Security.Principal.SecurityIdentifier $sidByte,0))
        }

            $ComplexArray = @()

            # Check numbers of direct groups
            $directgroups = (get-aduser -Identity $username -properties * | select -expand memberof).count

            # Check numbers of nested groups
            $nestedgroups = ($secirc.Translate([System.Security.Principal.NTAccount])).count
        
            # Status variable based on total group membership
            if($nestedgroups -gt 900)
            {
                $status = "Critical"
            }
            ElseIf($nestedgroups -gt 800)
            {
                $status = "Warning"
            }
            ElseIf($nestedgroups -lt 800)
            {
                $status = "Normal"
            }
 

            # Create a custom object 
            $ComplexObject = New-Object PSCustomObject
            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Username EID" -Value $username.Name
            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Status" -Value $status
            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Direct groups" -Value $directgroups
            $ComplexObject | Add-Member -MemberType NoteProperty -Name "Indirect groups (Nested)" -Value $nestedgroups

            # Add custom object to our array
            $ComplexArray += $ComplexObject
        
            # Display output in host
            $ComplexArray | ft -AutoSize -wrap


            # Confirm if you want to view output in pop-up window
            Write-Host " "
            Write-Host -NoNewLine "Do you want to view total $nestedgroups groups in new window? (Y/N) "
            $response = Read-Host
            Write-Host " "
 


        If ( $response -eq "Y" ) 
        { 
            $secirc.Translate([System.Security.Principal.NTAccount]) | Out-GridView -Title "Total Groups"
        }
 

    }


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.