Private/Interactive/New-TBSnapshotDiscovery.ps1
|
function New-TBSnapshotDiscovery { <# .SYNOPSIS Creates a temporary snapshot and extracts resource properties. .DESCRIPTION Shared helper for monitor creation workflows. Creates an auto-named snapshot with retry logic to handle resource types unsupported by the snapshot API, waits for completion, parses properties, and returns a result object. .PARAMETER ResourceTypes Array of resource type strings to include in the snapshot. .OUTPUTS [PSCustomObject] with properties: SnapshotId - ID of the created snapshot (null if none created) Properties - Hashtable mapping lowercase resource type to properties UnsupportedTypes - Array of types the snapshot API rejected Success - Boolean indicating whether usable properties were obtained #> [CmdletBinding()] [OutputType([PSCustomObject])] param( [Parameter(Mandatory = $true)] [string[]]$ResourceTypes ) $result = [PSCustomObject]@{ SnapshotId = $null Properties = @{} UnsupportedTypes = @() Success = $false } $snapName = 'TB AutoSnap {0}' -f (Get-Date -Format 'yyyyMMdd HHmmss') $snapTypes = @($ResourceTypes) $unsupportedBySnapshot = @() $snap = $null # Retry snapshot creation, filtering out types the snapshot API rejects for ($attempt = 0; $attempt -lt 3; $attempt++) { if ($snapTypes.Count -eq 0) { break } try { $snap = New-TBSnapshot -DisplayName $snapName -Resources $snapTypes -Confirm:$false break } catch { $newUnsupported = @() $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.message -match "ResourceType '([^']+)' is not supported") { $newUnsupported += $Matches[1] } } } if ($newUnsupported.Count -gt 0) { $unsupportedBySnapshot += $newUnsupported $snapTypes = @($snapTypes | Where-Object { $_.ToLower() -notin @($newUnsupported | ForEach-Object { $_.ToLower() }) }) continue } # Not an unsupported-type error -- rethrow throw } } $result.UnsupportedTypes = $unsupportedBySnapshot if ($snap) { $result.SnapshotId = $snap.Id $snap = Wait-TBSnapshotInteractive -SnapshotId $snap.Id -ResourceCount $snapTypes.Count if ($snap.Status -eq 'succeeded' -or $snap.Status -eq 'partiallySuccessful') { $result.Properties = Get-TBSnapshotResourceProperties -Snapshot $snap $result.Success = $true } } elseif ($unsupportedBySnapshot.Count -eq $ResourceTypes.Count) { # All types were unsupported by snapshot -- still a valid (empty) result $result.Success = $true } return $result } |