src/collect/ConvertTo-ScoutArcSiteResource.ps1
|
#Requires -Version 7.0 Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' <# .SYNOPSIS Materialize AZSC/ARMChild/ArcSites resource rows from Get-ScoutApiResources' ArcSites field. .DESCRIPTION `Microsoft.Edge/sites` (Azure Arc site manager) is a normal, non-extension ARM resource, but Resource Graph's supported-type reference does not list `microsoft.edge/sites` among the `microsoft.edge/*` types it indexes -- so a declarative collector reading the `resources` table for that type returns zero rows in every tenant, the same defect class AB#6769 fixed for Monitor/ResourceDiagnosticSettings. Because `Microsoft.Edge/sites` has no natural parent resource the way an extension resource does, `Get-ScoutApiResources.ps1` lists it once per subscription (`ArcSites` field) rather than through Get-ScoutArmChildResource.ps1's per-parent sweep. This is the pure transform that turns that per-subscription REST result into the `AZSC/ARMChild/ArcSites` resource rows the Hybrid/ArcSites declarative collector reads -- performs no Azure call and never mutates an input row, matching the shape of ConvertTo-ScoutAvdAzureLocalSessionHost.ps1 and Get-ScoutOutageResource.ps1. .PARAMETER ApiResources Per-subscription output from Get-ScoutApiResources. The `ArcSites` field is read; every other field is ignored. .OUTPUTS `[pscustomobject]` rows, one per site, each tagged `TYPE = 'AZSC/ARMChild/ArcSites'` with `subscriptionId` inherited from the owning subscription. A subscription whose sweep failed or whose ArcSites field is `$null` contributes zero rows and does not throw. .NOTES Tracks ADO AB#6801 (Feature AB#6747, Epic AB#6454). #> function ConvertTo-ScoutArcSiteResource { [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]]$ApiResources ) function Get-ArcSitePropertyValue { param( [Parameter(Mandatory)]$InputObject, [Parameter(Mandatory)][string[]]$Name ) foreach ($Candidate in $Name) { $Property = $InputObject.PSObject.Properties[$Candidate] if ($null -ne $Property) { return $Property.Value } } return $null } foreach ($ApiResult in @($ApiResources)) { if ($null -eq $ApiResult) { continue } $SubscriptionId = [string](Get-ArcSitePropertyValue -InputObject $ApiResult -Name @('Subscription', 'subscriptionId')) $SitesProperty = $ApiResult.PSObject.Properties['ArcSites'] if ($null -eq $SitesProperty -or $null -eq $SitesProperty.Value) { continue } foreach ($Site in @($SitesProperty.Value)) { if ($null -eq $Site) { continue } $SiteId = [string](Get-ArcSitePropertyValue -InputObject $Site -Name @('id', 'ID')) # ARM ids are always .../subscriptions/{sub}/resourceGroups/{rg}/providers/...; a site # created at subscription scope (no resource group segment) legitimately has none. $ResourceGroup = $null if (-not [string]::IsNullOrEmpty($SiteId)) { $Segments = $SiteId -split '/' $RgIndex = [array]::IndexOf($Segments, 'resourceGroups') if ($RgIndex -ge 0 -and $Segments.Count -gt ($RgIndex + 1)) { $ResourceGroup = $Segments[$RgIndex + 1] } } $Row = [ordered]@{} foreach ($Property in $Site.PSObject.Properties) { $Row[$Property.Name] = $Property.Value } $Row['TYPE'] = 'AZSC/ARMChild/ArcSites' $Row['subscriptionId'] = $SubscriptionId $Row['RESOURCEGROUP'] = $ResourceGroup [PSCustomObject]$Row } } } |