Private/Scanning/Get-SubAssignmentsRecursive.ps1
|
function Get-SubAssignmentsRecursive { <# .SYNOPSIS Get policy assignments from all subscriptions in the tenant. .DESCRIPTION Scans all enabled subscriptions in the tenant and retrieves their policy assignments. Automatically filters for direct assignments (excluding inherited). .PARAMETER EnabledOnly If true (default), only processes enabled subscriptions. Set to false to include all states. .EXAMPLE $allSubAssignments = Get-SubAssignmentsRecursive .OUTPUTS Array of policy assignment objects from all subscriptions #> [CmdletBinding()] param( [bool]$EnabledOnly = $true ) $assignments = @() try { Write-Host " ├─ Discovering ALL subscriptions in tenant..." -ForegroundColor DarkCyan $allSubs = Invoke-AzCommandWithRetry -Command { Get-AzSubscription -ErrorAction Stop } -OperationName "Subscription" # Track API type if ($script:ApiCallStats) { $script:ApiCallStats.SubscriptionCalls++ } if ($EnabledOnly) { $allSubs = $allSubs | Where-Object { $_.State -eq 'Enabled' } } Write-Host (" │ ├─ Found {0} {1}subscriptions" -f $allSubs.Count, $(if ($EnabledOnly) { "enabled " } else { "" })) -ForegroundColor DarkGray $subCount = 0 $subAssignmentCount = 0 $individualPolicyCount = 0 foreach ($sub in $allSubs) { $subCount++ try { $directSubAssignments = Get-SubAssignments -SubscriptionId $sub.Id -DirectOnly if ($directSubAssignments.Count -gt 0) { $directCount = ($directSubAssignments | Where-Object { $_.PolicyDefinitionId -like "*/policyDefinitions/*" -and $_.PolicyDefinitionId -notlike "*/policySetDefinitions/*" }).Count Write-Host (" │ ├─ [{0}/{1}] Sub '{2}': {3} assignments ({4} individual policies)" ` -f $subCount, $allSubs.Count, $sub.Name, $directSubAssignments.Count, $directCount) ` -ForegroundColor DarkGray $assignments += $directSubAssignments $subAssignmentCount += $directSubAssignments.Count $individualPolicyCount += $directCount } else { Write-Host (" │ ├─ [{0}/{1}] Sub '{2}': no direct assignments (all inherited)" ` -f $subCount, $allSubs.Count, $sub.Name) -ForegroundColor DarkGray } } catch { Write-Host (" │ ├─ [{0}/{1}] Sub '{2}': ERROR - {3}" ` -f $subCount, $allSubs.Count, $sub.Name, $_.Exception.Message) -ForegroundColor Red } } Write-Host "" Write-Host (" │ └─ Found {0} assignments across all subscriptions" -f $subAssignmentCount) -ForegroundColor Green Write-Host (" (Including {0} individual policies)" -f $individualPolicyCount) -ForegroundColor DarkGray } catch { Write-Warning "Cannot enumerate subscriptions: $($_.Exception.Message)" } return $assignments } |