Private/Invoke-WindowsDeviceLinkBackendTenantCatalog.ps1
|
function Invoke-WindowsDeviceLinkBackendTenantCatalog { [CmdletBinding()] param( [Parameter(Mandatory)][ValidateNotNull()][uri]$BackendUri, [Parameter(Mandatory)][ValidateNotNullOrEmpty()][string]$BackendApiKey, [ValidateRange(5,600)][int]$TimeoutSeconds = 120, [scriptblock]$RequestScript ) [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 $endpoint = Resolve-WindowsDeviceLinkBackendEndpoint -BackendUri $BackendUri -Route tenants $headers = @{ 'X-WindowsDeviceLink-Key' = $BackendApiKey } try { $response = if ($RequestScript) { & $RequestScript $endpoint $headers $TimeoutSeconds } else { Invoke-RestMethod -Method Get -Uri $endpoint -Headers $headers -TimeoutSec $TimeoutSeconds -ErrorAction Stop } if (-not $response -or $response.success -ne $true) { throw 'The Function tenant catalog did not succeed.' } if ([string]$response.apiVersion -ne '1.0') { throw "The Function backend API version '$($response.apiVersion)' is not supported; version 1.0 is required." } $requiredCapabilities = @('TenantCatalog','MultitenantLookup','Reconcile','Offboarding') $capabilities = @($response.capabilities) $missingCapabilities = @($requiredCapabilities | Where-Object { $_ -notin $capabilities }) if ($missingCapabilities.Count -gt 0) { throw "The Function backend is missing required capabilities: $($missingCapabilities -join ', ')." } $minimumVersion = $null if (-not [version]::TryParse([string]$response.minimumModuleVersion,[ref]$minimumVersion)) { throw 'The Function backend returned an invalid minimumModuleVersion.' } $loadedModule = Get-Module WindowsDeviceLink | Select-Object -First 1 if (-not $loadedModule -or $loadedModule.Version -lt $minimumVersion) { throw "The Function backend requires WindowsDeviceLink $minimumVersion or newer." } $tenants = @($response.tenants) if ($tenants.Count -eq 0 -or [int]$response.tenantCount -ne $tenants.Count) { throw 'The Function tenant catalog is empty or inconsistent.' } $seenIds = @{} $seenNames = @{} foreach ($tenant in $tenants) { $id = [guid]::Empty if (-not [guid]::TryParse([string]$tenant.tenantId,[ref]$id) -or [string]::IsNullOrWhiteSpace([string]$tenant.name)) { throw 'The Function tenant catalog contains an invalid tenant entry.' } $key = $id.ToString().ToLowerInvariant() if ($seenIds.ContainsKey($key)) { throw 'The Function tenant catalog contains a duplicate tenant ID.' } $seenIds[$key] = $true $nameKey = ([string]$tenant.name).Trim().ToLowerInvariant() if ($seenNames.ContainsKey($nameKey)) { throw 'The Function tenant catalog contains duplicate friendly names.' } $seenNames[$nameKey] = $true } $response } catch { $detail = Protect-WindowsDeviceLinkSensitiveText -Text ([string]$_.Exception.Message) -SensitiveValue @($BackendApiKey) throw ('WindowsDeviceLink Function tenant catalog failed. ' + $detail) } finally { $headers.Remove('X-WindowsDeviceLink-Key') | Out-Null } } |