src/collect/Get-ScoutTenantWideResource.ps1
|
#Requires -Version 7.0 Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' <# .SYNOPSIS Collect tenant-wide policy, custom-role, and management-group synthetic resources. .DESCRIPTION Produces the four typed resource envelopes that declarative collectors will consume after integration. Policy definitions are surfaced from Get-ScoutApiResources output already collected earlier in the collect phase. Custom roles are queried once for the tenant. Management groups are expanded once from the tenant root when possible, with the established enumerate-then-expand fallback for renamed or unreadable tenant roots. Every envelope is returned even when its properties array is empty. This makes the integration contract stable while allowing missing tenant-wide read permissions to degrade only the affected worksheet. .PARAMETER ApiResources Per-subscription output from Get-ScoutApiResources. PolicyDefinitions and PolicySetDefinitions are flattened into their corresponding typed envelopes. .OUTPUTS Exactly four PSCustomObjects, in stable type order. Each has `type` and `properties`: AZSC/Management/RoleDefinition AZSC/Management/ManagementGroup AZSC/Management/PolicyDefinition AZSC/Management/PolicySetDefinition .NOTES Isolated collect-phase implementation for AB#5933 (Epic AB#5917). Invoke-Collect does not call this function yet; old collectors remain the live path until definitions are ready. #> function Get-ScoutTenantWideResource { [CmdletBinding()] [OutputType([PSCustomObject])] Param( [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]]$ApiResources ) $PolicyDefinitions = @( foreach ($ApiResult in @($ApiResources)) { if ($null -ne $ApiResult -and $ApiResult.PSObject.Properties.Name -contains 'PolicyDefinitions' -and $null -ne $ApiResult.PolicyDefinitions) { @($ApiResult.PolicyDefinitions) | Where-Object { $null -ne $_ } } } ) $PolicySetDefinitions = @( foreach ($ApiResult in @($ApiResources)) { if ($null -ne $ApiResult -and $ApiResult.PSObject.Properties.Name -contains 'PolicySetDefinitions' -and $null -ne $ApiResult.PolicySetDefinitions) { @($ApiResult.PolicySetDefinitions) | Where-Object { $null -ne $_ } } } ) $CustomRoles = @() try { $CustomRoles = @( Get-AzRoleDefinition -Custom -ErrorAction Stop | Where-Object { $null -ne $_ } ) } catch { Write-Warning ( 'Get-ScoutTenantWideResource: custom role definitions could not be read; ' + "returning zero role rows and continuing: $($_.Exception.Message)" ) } $ExpandedRoots = @() $TenantId = $null try { $Context = Get-AzContext -ErrorAction SilentlyContinue if ($Context -and $Context.PSObject.Properties.Name -contains 'Tenant' -and $Context.Tenant -and $Context.Tenant.PSObject.Properties.Name -contains 'Id') { $TenantId = [string]$Context.Tenant.Id } } catch { Write-Verbose "Get-ScoutTenantWideResource: Azure context was unavailable: $($_.Exception.Message)" } if (-not [string]::IsNullOrWhiteSpace($TenantId)) { try { $ExpandedRoots = @( Get-AzManagementGroup -GroupId $TenantId -Expand -Recurse -ErrorAction Stop | Where-Object { $null -ne $_ } ) } catch { Write-Verbose ( "Get-ScoutTenantWideResource: tenant-root management-group expansion failed; " + "trying visible-group fallback: $($_.Exception.Message)" ) $ExpandedRoots = @() } } if ($ExpandedRoots.Count -eq 0) { try { $VisibleGroups = @( Get-AzManagementGroup -ErrorAction Stop | Where-Object { $null -ne $_ -and $_.PSObject.Properties.Name -contains 'Name' -and -not [string]::IsNullOrWhiteSpace([string]$_.Name) } ) $ExpandedGroups = @( foreach ($VisibleGroup in $VisibleGroups) { try { Get-AzManagementGroup -GroupId $VisibleGroup.Name -Expand -Recurse -ErrorAction Stop } catch { Write-Verbose ( "Get-ScoutTenantWideResource: management group '$($VisibleGroup.Name)' " + "could not be expanded: $($_.Exception.Message)" ) } } ) | Where-Object { $null -ne $_ } $RootGroups = @( $ExpandedGroups | Where-Object { $_.PSObject.Properties.Name -notcontains 'ParentName' -or [string]::IsNullOrWhiteSpace([string]$_.ParentName) } ) $ExpandedRoots = if ($RootGroups.Count -gt 0) { $RootGroups } else { $ExpandedGroups } } catch { Write-Warning ( 'Get-ScoutTenantWideResource: management groups could not be read; ' + "returning zero management-group rows and continuing: $($_.Exception.Message)" ) $ExpandedRoots = @() } } $ManagementGroups = @( if (@($ExpandedRoots).Count -gt 0) { ConvertTo-ScoutManagementGroupHierarchy -Root $ExpandedRoots } ) @( [PSCustomObject]@{ type = 'AZSC/Management/RoleDefinition' properties = @($CustomRoles) } [PSCustomObject]@{ type = 'AZSC/Management/ManagementGroup' properties = @($ManagementGroups) } [PSCustomObject]@{ type = 'AZSC/Management/PolicyDefinition' properties = @($PolicyDefinitions) } [PSCustomObject]@{ type = 'AZSC/Management/PolicySetDefinition' properties = @($PolicySetDefinitions) } ) } |