internal/functions/Build-ScopeTableForDeploymentRootScope.ps1
function Build-ScopeTableForDeploymentRootScope { param( [hashtable] $PacEnvironment ) $deploymentRootScope = $PacEnvironment.deploymentRootScope $tenantId = $PacEnvironment.tenantId Write-Information "" Write-Information "===================================================================================================" Write-Information "Get scope tree for EPAC environment '$($PacEnvironment.pacSelector)' at root scope $($deploymentRootScope -replace '/providers/Microsoft.Management','')" Write-Information "===================================================================================================" $scopeTable = @{} $tenantId = $PacEnvironment.tenantId $resourceGroupsBySubscriptionId = @{} $deploymentRootScopeSubscriptionId = $null $deploymentRootScopeManagementGroupName = $null $scopeSplat = $null $resourceGroupQuery = "resourcecontainers | where type == 'microsoft.resources/subscriptions/resourcegroups'" if ($deploymentRootScope.StartsWith("/providers/Microsoft.Management/managementGroups/")) { $deploymentRootScopeManagementGroupName = $deploymentRootScope -replace "/providers/Microsoft.Management/managementGroups/" $scopeSplat = @{ ManagementGroup = $deploymentRootScopeManagementGroupName } } elseif ($deploymentRootScope.StartsWith("/subscriptions/") -and $deploymentRootScope -notLike "*/resourceGroups/*") { $deploymentRootScopeSubscriptionId = $deploymentRootScope -replace "/subscriptions/" $scopeSplat = @{ Subscription = $deploymentRootScopeSubscriptionId } $resourceGroupQuery = "resourcecontainers | where type == 'microsoft.resources/subscriptions/resourcegroups' and subscriptionId == '$($deploymentRootScopeSubscriptionId)'" } else { throw "Invalid deploymentRootScope: $deploymentRootScope" } #region collect resource groups $resourceGroups = Search-AzGraphAllItems ` -Query $resourceGroupQuery ` -ScopeSplat $scopeSplat ` -ProgressItemName "Resource Groups" Write-Information "Processing $($resourceGroups.Count) Resource Groups..." foreach ($resourceGroup in $resourceGroups) { $subscriptionId = $resourceGroup.subscriptionId $id = $resourceGroup.id $isExcluded = $false $isInGlobalNotScope = $false foreach ($globalNotScope in $PacEnvironment.globalNotScopesResourceGroups) { if ($id -like $globalNotScope) { $isExcluded = $true $isInGlobalNotScope = $true break } } if (!$isExcluded) { foreach ($excludedScope in $PacEnvironment.globalExcludedScopesResourceGroups) { if ($id -like $excludedScope) { $isExcluded = $true break } } } $scopeDetails = @{ id = $resourceGroup.id type = $resourceGroup.type name = $resourceGroup.name displayName = $resourceGroup.name parentTable = @{} childrenTable = @{} resourceGroupsTable = @{} notScopesList = [System.Collections.ArrayList]::new() notScopesTable = @{} excludedScopesTable = @{} isExcluded = $isExcluded isInGlobalNotScope = $isInGlobalNotScope state = $resourceGroup.properties.provisioningState location = $resourceContainer.location } $resourceGroupList = $null if ($resourceGroupsBySubscriptionId.ContainsKey($subscriptionId)) { $resourceGroupList = $resourceGroupsBySubscriptionId.$subscriptionId } else { $resourceGroupList = [System.Collections.ArrayList]::new() $null = $resourceGroupsBySubscriptionId.Add($subscriptionId, $resourceGroupList) } $null = $resourceGroupList.Add($scopeDetails) } #endregion collect resource groups #region process subscriptions and/or management groups $scopeDetails = $null if ($null -ne $deploymentRootScopeSubscriptionId) { $subscription = Get-AzSubscription -SubscriptionId $deploymentRootScopeSubscriptionId -TenantId $tenantId -ErrorAction Stop $subscriptionId = $subscription.Id $scopeDetails = Build-ScopeTableForSubscription ` -SubscriptionId $subscriptionId ` -SubscriptionName $subscription.Name ` -ResourceGroupsBySubscriptionId $resourceGroupsBySubscriptionId ` -PacEnvironment $PacEnvironment ` -ScopeTable $scopeTable } else { $managementGroup = Get-AzManagementGroup -GroupName $deploymentRootScopeManagementGroupName -Expand -Recurse -ErrorAction Stop $scopeDetails = Build-ScopeTableForManagementGroup ` -ManagementGroup $managementGroup ` -ResourceGroupsBySubscriptionId $resourceGroupsBySubscriptionId ` -PacEnvironment $PacEnvironment ` -ScopeTable $scopeTable } $null = $scopeTable.Add($scopeDetails.id, $scopeDetails) $null = $scopeTable.Add("root", $scopeDetails) # count each type of scope $numberOfManagementGroups = 0 $numberOfSubscriptions = 0 $numberofResourceGroups = 0 foreach ($scopeDetails in $scopeTable.Values) { if ($scopeDetails.type -eq "Microsoft.Management/managementGroups") { $numberOfManagementGroups++ } elseif ($scopeDetails.type -eq "/subscriptions") { $numberOfSubscriptions++ } elseif ($scopeDetails.type -eq "microsoft.resources/subscriptions/resourcegroups") { $numberofResourceGroups++ } } #endregion process subscriptions and/or management groups Write-Information "" Write-Information "Scope tree for EPAC environment '$($PacEnvironment.pacSelector)' at root scope $($deploymentRootScope -replace '/providers/Microsoft.Management','') complete." if ($numberOfManagementGroups -gt 0) { $numberOfManagementGroups-- # subtract 1 for the root scope Write-Information " Management groups = $($numberOfManagementGroups)" } if ($deploymentRootScope.StartsWith("/subscriptions/")) { $numberOfSubscriptions-- # subtract 1 for the root scope } Write-Information " Subscriptions = $($numberOfSubscriptions)" Write-Information " Resource groups = $($numberofResourceGroups)" return $scopeTable } |