Private/Invoke-PVESnapshotOperation.ps1
|
function Invoke-PVESnapshotOperation { <# .SYNOPSIS Shared engine for the snapshot cmdlets: one request per guest and snapshot, waited for together. .DESCRIPTION For each item ({ Guest; Snapshot }), asks ShouldProcess on the calling cmdlet with -Description (where {snapshot} is replaced by the snapshot name), then sends -Method to /nodes/{node}/{type}/{vmid}/snapshot plus -Suffix ('{snapshot}' in it is replaced by the URL-escaped name), with -Body ('{snapshot}' in a value is replaced too). Then waits for all tasks (Wait-PVEOperation) and writes, per -Output: Snapshot, the snapshot as it now is; Guest, the guest with its live status; None, nothing. With -RunAsync, writes the tasks instead. #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '', Justification = 'Calls ShouldProcess on the calling public cmdlet, passed as -Cmdlet, so its -WhatIf and -Confirm apply.')] [CmdletBinding()] [OutputType([psobject])] param( [Parameter(Mandatory)] [System.Management.Automation.PSCmdlet]$Cmdlet, [Parameter(Mandatory)] [AllowEmptyCollection()] [psobject[]]$Item, [Parameter(Mandatory)] [ValidateSet('POST', 'PUT', 'DELETE')] [string]$Method, [AllowEmptyString()] [string]$Suffix = '', [hashtable]$Body = @{}, [Parameter(Mandatory)] [string]$Description, [Parameter(Mandatory)] [ValidateSet('Snapshot', 'Guest', 'None')] [string]$Output, [switch]$RunAsync ) $operations = [System.Collections.Generic.List[psobject]]::new() foreach ($entry in $Item) { $guest = $entry.Guest $name = $entry.Snapshot if (-not $Cmdlet.ShouldProcess((Get-PVEGuestLabel -Guest $guest), $Description.Replace('{snapshot}', $name))) { continue } $path = Format-PVEPath '/nodes/{node}/{type}/{vmid}/snapshot' @{ node = $guest.Node; type = $guest.Type; vmid = $guest.VMId } $path += $Suffix.Replace('{snapshot}', [uri]::EscapeDataString($name)) $parameters = @{} foreach ($key in $Body.Keys) { $value = $Body[$key] $parameters[$key] = if ($value -is [string]) { $value.Replace('{snapshot}', $name) } else { $value } } try { $result = [string](Invoke-PVERequest -Connection $guest.Connection -Method $Method -Path $path -Parameters $parameters) } catch { $Cmdlet.WriteError($_) continue } Write-Verbose "$($Description.Replace('{snapshot}', $name)) on $(Get-PVEGuestLabel -Guest $guest): $(if ($result) { "task $result" } else { 'done' })" $operations.Add([pscustomobject]@{ Upid = $result; Connection = $guest.Connection; Guest = $guest; Snapshot = $name }) } if ($operations.Count -eq 0) { return } if ($RunAsync) { foreach ($op in $operations) { if ($op.Upid -match '^UPID:') { try { Get-PVETask -Upid $op.Upid -Server $op.Connection -ErrorAction Stop } catch { $Cmdlet.WriteError($_) } } } return } foreach ($op in @(Wait-PVEOperation -Operation $operations)) { try { switch ($Output) { 'Snapshot' { Get-PVEGuestSnapshot -Guest $op.Guest | Where-Object { $_.Snapshot -eq $op.Snapshot } } 'Guest' { Update-PVEGuestStatus -Guest $op.Guest } } } catch { $Cmdlet.WriteError($_) } } } |