PoshCode Archive  Artifact [b675fc8035]

Artifact b675fc8035059d4fd6bfee209077dc7f354eb5374965732c690190fc4ce29691:

  • File Get-QADGroupNesting.ps1 — part of check-in [37e9faaa2b] at 2018-06-10 12:58:54 on branch trunk — I came across an article on the “Microsoft Active Directory PowerShell Blog”, it has a great script for analysing nested group memberships. Unfortunatly to use the PowerShell script you need to be running Windows 2008 servers for the Active Directory cmdlets to be available. So not put off I converted the script to use the Quest cmdlets available with the “Quest Active Roles Management” PSSnapIn. You will need to have these installed for the script to function. (user: unknown size: 4456)

# encoding: utf-8
# api: powershell
# title: Get-QADGroupNesting
# description: I came across an article on the “Microsoft Active Directory PowerShell Blog”, it has a great script for analysing nested group memberships. Unfortunatly to use the PowerShell script you need to be running Windows 2008 servers for the Active Directory cmdlets to be available. So not put off I converted the script to use the Quest cmdlets available with the “Quest Active Roles Management” PSSnapIn. You will need to have these installed for the script to function.
# version: 0.1
# type: function
# license: CC0
# function: Get-GroupNesting
# x-poshcode-id: 1595
# x-derived-from-id: 1890
# x-archived: 2010-07-18T14:39:24
#
# Original Script: http://blogs.msdn.com/adpowershell/archive/2009/09/05/token-bloat-troubleshooting-by-analyzing-group-nesting-in-ad.aspx
# Save the code as: Get-QADGroupNesting.ps1
# Usage: PS C:\> ./Get-QADGroupNesting.ps1 groupdisplayname -ShowTree
#
Param (
    [Parameter(Mandatory=$true,
        Position=0,
        ValueFromPipeline=$true,
        HelpMessage="DN or ObjectGUID of the AD Group."
    )]
    [string]$groupIdentity,
    [switch]$showTree
    )
#Validate Quest PSSnapin is loaded
Add-PSSnapin -Name Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$global:numberOfRecursiveGroupMemberships = 0
$lastGroupAtALevelFlags = @() 

function Get-GroupNesting ([string] $identity, [int] $level, [hashtable] $groupsVisitedBeforeThisOne, [bool] $lastGroupOfTheLevel)
{
    $group = $null
    $group = Get-QADGroup -Identity $identity -SizeLimit 0
    if($lastGroupAtALevelFlags.Count -le $level)
    {
        $lastGroupAtALevelFlags = $lastGroupAtALevelFlags + 0
    }
    if($group -ne $null)
    {
        if($showTree)
        {
            for($i = 0; $i -lt $level - 1; $i++)
            {
                if($lastGroupAtALevelFlags[$i] -ne 0)
                {
                    Write-Host -ForegroundColor Blue -NoNewline "  "
                }
                else
                {
                    Write-Host -ForegroundColor Blue -NoNewline "  "
                }
            }
            if($level -ne 0)
            {
                if($lastGroupOfTheLevel)
                {
                    Write-Host -ForegroundColor Blue -NoNewline "¤"
                }
                else
                {
                    Write-Host -ForegroundColor Blue -NoNewline "¥"
                }
            }
            Write-Host -ForegroundColor Blue $group.Name
        }
        $groupsVisitedBeforeThisOne.Add($group.DN,$null)
        $global:numberOfRecursiveGroupMemberships ++
        $groupMemberShipCount = $group.memberOf.Count
        if ($groupMemberShipCount -gt 0)
        {
            $maxMemberGroupLevel = 0
            $count = 0
            foreach($groupDN in $group.memberOf)
            {
                $count++
                $lastGroupOfThisLevel = $false
                if($count -eq $groupMemberShipCount){$lastGroupOfThisLevel = $true; $lastGroupAtALevelFlags[$level] = 1}
                if(-not $groupsVisitedBeforeThisOne.Contains($groupDN)) #prevent cyclic dependancies
                {
                    $memberGroupLevel = Get-GroupNesting -Identity $groupDN -Level $($level+1) -GroupsVisitedBeforeThisOne $groupsVisitedBeforeThisOne -lastGroupOfTheLevel $lastGroupOfThisLevel
                    if ($memberGroupLevel -gt $maxMemberGroupLevel){$maxMemberGroupLevel = $memberGroupLevel}
                }
            }
            $level = $maxMemberGroupLevel
        }
        else #we've reached the top level group, return it's height
        {
            return $level
        }
        return $level
    }
}
$global:numberOfRecursiveGroupMemberships = 0
$groupObj = Get-QADGroup -Identity $groupIdentity -SizeLimit 0
if($groupObj)
{
    [int]$maxNestingLevel = Get-GroupNesting -Identity $groupIdentity -Level 0 -GroupsVisitedBeforeThisOne @{} -lastGroupOfTheLevel $false
	Add-Member -InputObject $groupObj -MemberType NoteProperty  -Name MaxNestingLevel -Value $maxNestingLevel -Force
    Add-Member -InputObject $groupObj -MemberType NoteProperty  -Name NestedGroupMembershipCount -Value $($global:numberOfRecursiveGroupMemberships - 1) -Force
	$groupObj | Select-Object Name,DN,MaxNestingLevel,NestedGroupMembershipCount | Format-List
}