Private/Scanning/Get-MgAssignmentsRecursive.ps1
|
function Get-MgAssignmentsRecursive { <# .SYNOPSIS Get policy assignments from all Management Groups in the tenant. .DESCRIPTION Recursively scans all Management Groups in the tenant and retrieves their policy assignments. Useful for comprehensive tenant-wide analysis. .PARAMETER ExcludeRootMg Optional Management Group ID to exclude from scanning (typically the root MG already scanned by Get-MgAssignments). .EXAMPLE $allMgAssignments = Get-MgAssignmentsRecursive -ExcludeRootMg "MyRootMG" .OUTPUTS Array of policy assignment objects from all MGs #> [CmdletBinding()] param( [string]$ExcludeRootMg ) $assignments = @() try { Write-Host " ├─ Discovering all Management Groups in tenant..." -ForegroundColor DarkCyan $allMgs = Invoke-AzCommandWithRetry -Command { Get-AzManagementGroup -ErrorAction Stop } -OperationName "ManagementGroup" # Track API type if ($script:ApiCallStats) { $script:ApiCallStats.ManagementGroupCalls++ } Write-Host (" │ ├─ Total MGs found: {0}" -f $allMgs.Count) -ForegroundColor DarkGray $mgCount = 0 $mgAssignmentCount = 0 foreach ($childMg in $allMgs) { # Skip excluded MG (typically root already scanned) if ($ExcludeRootMg -and $childMg.Name -eq $ExcludeRootMg) { continue } $mgCount++ # Progress indicator every 5 MGs if ($mgCount % 5 -eq 0 -or $mgCount -eq $allMgs.Count) { Write-Host ("`r │ ├─ [{0}/{1}] Scanning MGs..." -f $mgCount, $allMgs.Count) -NoNewline -ForegroundColor DarkGray } try { $childMgScope = "/providers/Microsoft.Management/managementGroups/$($childMg.Name)" $childMgAssignments = Invoke-AzCommandWithRetry -Command { Get-AzPolicyAssignment -Scope $childMgScope -ErrorAction SilentlyContinue } -OperationName "PolicyAssignment" # Track API type if ($script:ApiCallStats) { $script:ApiCallStats.PolicyAssignmentCalls++ } if ($childMgAssignments) { $assignments += $childMgAssignments $mgAssignmentCount += $childMgAssignments.Count } } catch { Write-Debug "Cannot scan MG $($childMg.Name): $($_.Exception.Message)" } } Write-Host "" Write-Host (" │ └─ Found {0} assignments across all MGs" -f $mgAssignmentCount) -ForegroundColor Green } catch { Write-Warning "Cannot enumerate Management Groups: $($_.Exception.Message)" } return $assignments } |