#requires –Modules ActiveDirectory -version 3.0 clear-host #NB: currently assumes that all users & groups are in the same domain function Get-AdGroupHierarchy { [cmdletbinding()] param( [parameter(Mandatory = $true, ValueFromPipeline = $true)] [string]$AdGroupSamAccountName , [parameter(Mandatory = $false)] [int]$Level = 0 , [parameter(Mandatory = $false)] [string]$DisplayField = 'SamAccountName' #allows us to use names instead of samAccountNames if desired; though faster if we just use the sAmAccountName as avoids a lookup per call , [parameter(Mandatory = $false)] [switch]$IncludeManagedBy ) begin { [string[]]$DefaultDisplayProperties = @('Directory') if($IncludeManagedBy){ $DefaultDisplayProperties += 'ManagedBy' } } process { [string]$managedBy = '' [string]$displayName = $AdGroupSamAccountName if(($DisplayField -ne 'SamAccountName') -or ($IncludeManagedBy)) { #save an ad lookup if not required $group = Get-AdGroup $AdGroupSamAccountName -Properties ManagedBy, $DisplayField $displayName = $group | Select-Object -ExpandProperty $DisplayField if (($IncludeManagedBy) -and ($group.ManagedBy)) { $managedBy = $group.ManagedBy | Get-AdUser -Properties DisplayName | Select-Object -ExpandProperty DisplayName } } (new-object -TypeName PSObject -Property ([ordered]@{ Level = $Level DisplayName = $DisplayName })) ` | %{if($IncludeManagedBy){$_ | Add-Member -MemberType NoteProperty -Name ManagedBy -Value $managedBy -PassThru}else{$_}} ` | Add-Member -MemberType ScriptProperty -Name DirectorySpacer -Value {("`t" * $this.Level) + ('|- ' * ($this.Level -gt 0))} -PassThru ` | Add-Member -MemberType ScriptProperty -Name Directory -Value {$this.DirectorySpacer + $this.DisplayName} -PassThru ` | Add-Member -MemberType MemberSet -Name PSStandardMembers -Value ([System.Management.Automation.PSMemberInfo[]](New-Object System.Management.Automation.PSPropertySet DefaultDisplayPropertySet, $DefaultDisplayProperties)) -PassThru Get-AdGroupMember $AdGroupSamAccountName | ?{$_.objectClass -eq 'group'} | Select-Object -ExpandProperty SamAccountName | Sort-Object | Get-AdGroupHierarchy -Level ($level + 1) -DisplayField $DisplayField -IncludeManagedBy:$IncludeManagedBy } } Get-AdGroupHierarchy 'MyAdGroupSamAccountName' #see just the directory structure Get-AdGroupHierarchy 'MyAdGroupSamAccountName' -IncludeManagedBy | ft -AutoSize #see directory structure and manager Get-AdGroupHierarchy 'MyAdGroupSamAccountName' -IncludeManagedBy | select * #see all properties being returned