Private/Interactive/Invoke-TBMonitorCreateWithRetry.ps1
|
function Invoke-TBMonitorCreateWithRetry { <# .SYNOPSIS Creates a monitor with retry logic for rejected resource types. .DESCRIPTION Wraps New-TBMonitor with a retry loop that parses the API error response to identify resource types the monitor API does not support (e.g. types unsupported in monitorOnly run mode, or types with empty properties). Rejected types are removed from the resources list and the call is retried. .PARAMETER DisplayName Monitor display name. .PARAMETER Description Optional monitor description. .PARAMETER Resources Array of resource objects (resourceType, displayName, properties). .OUTPUTS [PSCustomObject] with properties: Result - The created monitor object (null on failure) RejectedTypes - Array of resource type names the monitor API rejected #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)] [string]$DisplayName, [Parameter()] [string]$Description, [Parameter(Mandatory = $true)] [object[]]$Resources ) $output = [PSCustomObject]@{ Result = $null RejectedTypes = @() } $currentResources = @($Resources) for ($attempt = 0; $attempt -lt 3; $attempt++) { if ($currentResources.Count -eq 0) { break } $params = @{ DisplayName = $DisplayName Resources = $currentResources Confirm = $false } if ($Description) { $params['Description'] = $Description } try { $output.Result = New-TBMonitor @params return $output } catch { # Parse rejected resource types from error details $rejectedInAttempt = @() $errBody = $null $jsonText = $null if ($_.ErrorDetails -and $_.ErrorDetails.Message) { $edm = $_.ErrorDetails.Message if ($edm -match '(\r?\n){2}') { $parts = $edm -split '(?:\r?\n){2}', 2 if ($parts.Count -eq 2 -and $parts[1].Trim()) { $jsonText = $parts[1].Trim() } } if (-not $jsonText) { $jsonText = $edm } } if (-not $jsonText) { $jsonText = $_.Exception.Message } if ($jsonText) { try { $errBody = $jsonText | ConvertFrom-Json } catch {} } if ($errBody.error.details) { foreach ($detail in $errBody.error.details) { if ($detail.target -and ( $detail.message -match 'is not supported' -or $detail.message -match 'properties cannot be empty' )) { if ($detail.target -notin $rejectedInAttempt) { $rejectedInAttempt += $detail.target } } } } if ($rejectedInAttempt.Count -gt 0) { $output.RejectedTypes += $rejectedInAttempt $rejectedLower = @($rejectedInAttempt | ForEach-Object { $_.ToLower() }) $currentResources = @($currentResources | Where-Object { $_.resourceType.ToLower() -notin $rejectedLower }) continue } # Not a resource-type rejection error -- rethrow throw } } # All resources were rejected return $output } |