Public/VM/Move-VergeVM.ps1
|
function Move-VergeVM { <# .SYNOPSIS Moves a VergeOS virtual machine to a different node. .DESCRIPTION Move-VergeVM live-migrates a running VM to another node in the cluster, or moves a stopped VM to a different node. This is useful for load balancing, maintenance, or failover scenarios. .PARAMETER VM A VM object from Get-VergeVM. Accepts pipeline input. .PARAMETER Name The name of the VM to move. .PARAMETER Key The key (ID) of the VM to move. .PARAMETER DestinationNode The key (ID) of the destination node to move to. If not specified, VergeOS will automatically select an appropriate node. .PARAMETER PassThru Return the VM object after the move. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Move-VergeVM -Name "WebServer01" Moves the VM to an automatically selected node. .EXAMPLE Move-VergeVM -Name "WebServer01" -DestinationNode 5 Moves the VM to the node with key 5. .EXAMPLE Get-VergeVM -Name "Prod-*" | Move-VergeVM -DestinationNode 3 Moves all production VMs to node 3. .EXAMPLE Move-VergeVM -Name "Database01" -PassThru | Select-Object Name, PowerState Moves the VM and returns its status. .OUTPUTS None by default. Verge.VM when -PassThru is specified. .NOTES Live migration of running VMs requires sufficient resources on the destination node. Stopped VMs can be moved without resource constraints. Migration time depends on VM memory size and network speed. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByName')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByVM')] [PSTypeName('Verge.VM')] [PSCustomObject]$VM, [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByName')] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByKey')] [int]$Key, [Parameter()] [int]$DestinationNode, [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 { # Resolve VM based on parameter set $targetVMs = switch ($PSCmdlet.ParameterSetName) { 'ByName' { Get-VergeVM -Name $Name -Server $Server } 'ByKey' { Get-VergeVM -Key $Key -Server $Server } 'ByVM' { $VM } } foreach ($targetVM in $targetVMs) { if (-not $targetVM) { continue } # Check if VM is a snapshot if ($targetVM.IsSnapshot) { Write-Error -Message "Cannot move '$($targetVM.Name)': VM is a snapshot" -ErrorId 'CannotMoveSnapshot' continue } # Build action body $body = @{ vm = $targetVM.Key action = 'migrate' } if ($DestinationNode) { $body['params'] = @{ node = $DestinationNode } } $destDesc = if ($DestinationNode) { " to node $DestinationNode" } else { ' to auto-selected node' } if ($PSCmdlet.ShouldProcess($targetVM.Name, "Move VM$destDesc")) { try { Write-Verbose "Moving VM '$($targetVM.Name)'$destDesc" $response = Invoke-VergeAPI -Method POST -Endpoint 'vm_actions' -Body $body -Connection $Server Write-Verbose "Move initiated for VM '$($targetVM.Name)'" if ($PassThru) { # Wait briefly for migration to start/complete Start-Sleep -Seconds 2 Get-VergeVM -Key $targetVM.Key -Server $Server } } catch { Write-Error -Message "Failed to move VM '$($targetVM.Name)': $($_.Exception.Message)" -ErrorId 'MoveFailed' } } } } } |