Public/VM/Restart-VergeVM.ps1
|
function Restart-VergeVM { <# .SYNOPSIS Restarts a VergeOS virtual machine. .DESCRIPTION Restart-VergeVM reboots one or more virtual machines. By default, a graceful reboot is performed (ACPI signal). Use -Force to perform a hard reset, equivalent to pressing the physical reset button. .PARAMETER Name The name of the VM to restart. Supports wildcards (* and ?). .PARAMETER Key The unique key (ID) of the VM to restart. .PARAMETER VM A VM object from Get-VergeVM. Accepts pipeline input. .PARAMETER Force Perform a hard reset instead of graceful reboot. Use this when the guest OS is unresponsive. .PARAMETER PassThru Return the VM object after restarting. By default, no output is returned. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Restart-VergeVM -Name "WebServer01" Gracefully reboots the VM named "WebServer01". .EXAMPLE Restart-VergeVM -Name "WebServer01" -Force Performs a hard reset on the VM (like pressing the reset button). .EXAMPLE Get-VergeVM -Name "App*" -PowerState Running | Restart-VergeVM Gracefully reboots all running VMs starting with "App". .EXAMPLE Restart-VergeVM -Name "FrozenVM" -Force -Confirm:$false Hard resets an unresponsive VM without confirmation. .OUTPUTS None by default. Verge.VM when -PassThru is specified. .NOTES Graceful restart requires the QEMU Guest Agent to be installed and running inside the VM. If the guest agent is not available, use -Force for a hard reset. Use -Force when the guest OS is unresponsive (equivalent to reset button). #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByName')] [SupportsWildcards()] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByKey')] [int]$Key, [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByVM')] [PSTypeName('Verge.VM')] [PSCustomObject]$VM, [Parameter()] [switch]$Force, [Parameter()] [switch]$PassThru, [Parameter()] [object]$Server ) begin { # Resolve connection if (-not $Server) { $Server = $script:DefaultConnection } if (-not $Server) { throw [System.InvalidOperationException]::new( 'Not connected to VergeOS. Use Connect-VergeOS to establish a connection.' ) } } process { # Get VMs to restart based on parameter set $vmsToRestart = switch ($PSCmdlet.ParameterSetName) { 'ByName' { Get-VergeVM -Name $Name -Server $Server } 'ByKey' { Get-VergeVM -Key $Key -Server $Server } 'ByVM' { $VM } } foreach ($targetVM in $vmsToRestart) { if (-not $targetVM) { continue } # Check if VM is a snapshot if ($targetVM.IsSnapshot) { Write-Error -Message "Cannot restart VM '$($targetVM.Name)': VM is a snapshot" -ErrorId 'CannotRestartSnapshot' continue } # Check if VM is running if ($targetVM.PowerState -ne 'Running') { Write-Warning "VM '$($targetVM.Name)' is not running (state: $($targetVM.PowerState)). Use Start-VergeVM to power on." if ($PassThru) { Write-Output $targetVM } continue } # Check if graceful restart is requested but guest agent is not enabled if (-not $Force -and -not $targetVM.GuestAgent) { Write-Warning "VM '$($targetVM.Name)' does not have guest agent enabled. Graceful restart requires the QEMU Guest Agent. Use -Force for a hard reset instead." continue } # Determine action type # reset = hard reset (like reset button) # guestreset = graceful reboot (ACPI signal, requires guest agent) $action = if ($Force) { 'reset' } else { 'guestreset' } $actionVerb = if ($Force) { 'Hard reset' } else { 'Gracefully restart' } # Build action body $body = @{ vm = $targetVM.Key action = $action } # Confirm action if ($PSCmdlet.ShouldProcess($targetVM.Name, "$actionVerb VM")) { try { Write-Verbose "$actionVerb VM '$($targetVM.Name)' (Key: $($targetVM.Key))" $response = Invoke-VergeAPI -Method POST -Endpoint 'vm_actions' -Body $body -Connection $Server Write-Verbose "Restart command sent for VM '$($targetVM.Name)'" if ($PassThru) { # Return refreshed VM object Start-Sleep -Milliseconds 500 Get-VergeVM -Key $targetVM.Key -Server $Server } } catch { $errorMessage = $_.Exception.Message # Provide more helpful message for guest agent issues if (-not $Force -and ($errorMessage -match '422' -or $errorMessage -match 'guest')) { Write-Error -Message "Failed to gracefully restart VM '$($targetVM.Name)': Guest agent may not be running. Use -Force for a hard reset." -ErrorId 'GuestAgentRequired' } else { Write-Error -Message "Failed to restart VM '$($targetVM.Name)': $errorMessage" -ErrorId 'VMRestartFailed' } } } } } } |