Public/VM/Set-VergeDrive.ps1
|
function Set-VergeDrive { <# .SYNOPSIS Modifies a VergeOS virtual machine drive configuration. .DESCRIPTION Set-VergeDrive updates the configuration of an existing VM drive. Can change size (grow only), tier, interface, and other settings. .PARAMETER Drive A drive object from Get-VergeDrive. Accepts pipeline input. .PARAMETER Key The key (ID) of the drive to modify. .PARAMETER Name The new name for the drive. .PARAMETER SizeGB The new size in gigabytes. Can only grow, not shrink. .PARAMETER Interface The drive interface type. Valid values: virtio, ide, ahci, nvme, virtio-scsi, virtio-scsi-dedicated .PARAMETER Tier The preferred storage tier (1-5). .PARAMETER Description The description for the drive. .PARAMETER ReadOnly Set the drive to read-only or read-write. .PARAMETER Enabled Enable or disable the drive. .PARAMETER MediaSource The media source file key (for CD-ROM drives to mount ISO). .PARAMETER PassThru Return the modified drive object. .PARAMETER Server The VergeOS connection to use. Defaults to the current default connection. .EXAMPLE Get-VergeDrive -VMName "WebServer01" -Name "DataDisk" | Set-VergeDrive -SizeGB 200 Grows the DataDisk to 200GB. .EXAMPLE Set-VergeDrive -Key 123 -Tier 1 -PassThru Moves the drive to tier 1 storage and returns the updated object. .EXAMPLE Get-VergeDrive -VMName "WebServer01" | Where-Object { $_.Media -eq 'cdrom' } | Set-VergeDrive -MediaSource 456 Mounts an ISO file to the CD-ROM drive. .EXAMPLE Get-VergeDrive -VMName "WebServer01" -Name "OldDisk" | Set-VergeDrive -Enabled $false Disables the drive. .OUTPUTS None by default. Verge.Drive when -PassThru is specified. .NOTES Disk size can only be increased, not decreased. Some changes may require the VM to be powered off. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByDrive')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByDrive')] [PSTypeName('Verge.Drive')] [PSCustomObject]$Drive, [Parameter(Mandatory, ParameterSetName = 'ByKey')] [int]$Key, [Parameter()] [ValidateLength(1, 128)] [string]$Name, [Parameter()] [ValidateRange(1, 65536)] [int]$SizeGB, [Parameter()] [ValidateSet('virtio', 'ide', 'ahci', 'nvme', 'virtio-scsi', 'virtio-scsi-dedicated')] [string]$Interface, [Parameter()] [ValidateRange(1, 5)] [ValidateScript({ if ($_ -eq 0) { throw "Tier 0 is reserved for system metadata and cannot be used for VM drives." } $true })] [int]$Tier, [Parameter()] [ValidateLength(0, 2048)] [string]$Description, [Parameter()] [Nullable[bool]]$ReadOnly, [Parameter()] [Nullable[bool]]$Enabled, [Parameter()] [int]$MediaSource, [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 drive key $driveKey = switch ($PSCmdlet.ParameterSetName) { 'ByDrive' { $Drive.Key } 'ByKey' { $Key } } $driveName = if ($Drive) { $Drive.Name } else { "Key $driveKey" } $vmName = if ($Drive -and $Drive.VMName) { $Drive.VMName } else { 'Unknown' } # Build update body with only changed properties $body = @{} if ($PSBoundParameters.ContainsKey('Name')) { $body['name'] = $Name } if ($PSBoundParameters.ContainsKey('SizeGB')) { $body['disksize'] = [int64]$SizeGB * 1073741824 } if ($PSBoundParameters.ContainsKey('Interface')) { $body['interface'] = $Interface } if ($PSBoundParameters.ContainsKey('Tier')) { $body['preferred_tier'] = $Tier.ToString() } if ($PSBoundParameters.ContainsKey('Description')) { $body['description'] = $Description } if ($PSBoundParameters.ContainsKey('ReadOnly')) { $body['readonly'] = $ReadOnly } if ($PSBoundParameters.ContainsKey('Enabled')) { $body['enabled'] = $Enabled } if ($PSBoundParameters.ContainsKey('MediaSource')) { $body['media_source'] = $MediaSource } if ($body.Count -eq 0) { Write-Warning "No changes specified for drive '$driveName'" return } $changes = ($body.Keys | ForEach-Object { $_ }) -join ', ' if ($PSCmdlet.ShouldProcess("$driveName (VM: $vmName)", "Modify drive ($changes)")) { try { Write-Verbose "Modifying drive '$driveName' (Key: $driveKey)" $response = Invoke-VergeAPI -Method PUT -Endpoint "machine_drives/$driveKey" -Body $body -Connection $Server Write-Verbose "Drive '$driveName' modified successfully" if ($PassThru) { # Return updated drive $driveResponse = Invoke-VergeAPI -Method GET -Endpoint "machine_drives/$driveKey" -Connection $Server if ($driveResponse) { # Handle null/zero sizes gracefully (CDROM drives have no disksize) # Use unique variable names to avoid parameter validation conflicts $outputSizeBytes = if ($null -ne $driveResponse.disksize) { [long]$driveResponse.disksize } else { [long]0 } $outputSizeGigabytes = if ($outputSizeBytes -gt 0) { [math]::Round($outputSizeBytes / 1073741824, 2) } else { [double]0 } # Build output object $output = New-Object PSObject $output.PSObject.TypeNames.Insert(0, 'Verge.Drive') $output | Add-Member -NotePropertyName Key -NotePropertyValue ($driveResponse.'$key' ?? $driveKey) $output | Add-Member -NotePropertyName Name -NotePropertyValue $driveResponse.name $output | Add-Member -NotePropertyName Interface -NotePropertyValue $driveResponse.interface $output | Add-Member -NotePropertyName Media -NotePropertyValue $driveResponse.media $output | Add-Member -NotePropertyName SizeGB -NotePropertyValue $outputSizeGigabytes $output | Add-Member -NotePropertyName SizeBytes -NotePropertyValue $outputSizeBytes $output | Add-Member -NotePropertyName Tier -NotePropertyValue $driveResponse.preferred_tier $output | Add-Member -NotePropertyName Enabled -NotePropertyValue $driveResponse.enabled $output | Add-Member -NotePropertyName ReadOnly -NotePropertyValue $driveResponse.readonly $output | Add-Member -NotePropertyName Description -NotePropertyValue $driveResponse.description $output | Add-Member -NotePropertyName MachineKey -NotePropertyValue $driveResponse.machine $output | Add-Member -NotePropertyName MediaSource -NotePropertyValue $driveResponse.media_source $output | Add-Member -NotePropertyName OrderId -NotePropertyValue $driveResponse.orderid Write-Output $output } } } catch { Write-Error -Message "Failed to modify drive '$driveName': $($_.Exception.Message)" -ErrorId 'DriveModifyFailed' } } } } |