Public/volume.ps1
|
function Get-CSVolume { <# .SYNOPSIS Lists disk volumes. .DESCRIPTION Retrieves volumes (listVolumes) with optional filtering. Accepts VM objects (or VM names) on the pipeline and lists the volumes attached to each VM, so 'Get-CSVM web-01 | Get-CSVolume' returns that VM's disks. .PARAMETER Id Filter by volume ID .PARAMETER Ids Filter by several volume IDs. Mutually exclusive with -Id. .PARAMETER Name Filter by volume name .PARAMETER Keyword Filter by keyword (partial match) .PARAMETER VM A VM name or VM object whose volumes to list. Binds from the pipeline. .PARAMETER VirtualMachineId List the volumes attached to this VM ID .PARAMETER Type Filter by disk type: ROOT or DATADISK .PARAMETER State Filter by volume state .PARAMETER ZoneId Filter by zone ID .PARAMETER PodId Filter by pod ID .PARAMETER ClusterId Filter by cluster ID .PARAMETER HostId Filter by host ID .PARAMETER StorageId Filter by primary storage pool ID (root admin only) .PARAMETER DiskOfferingId Filter by disk offering ID .PARAMETER ServiceOfferingId Filter by the service offering of the VM the volume belongs to. Ignored when -DiskOfferingId is also given. .PARAMETER Tags Filter by resource tags, as a hashtable of key = value pairs .PARAMETER Account Filter by account name. Must be used with -DomainId. .PARAMETER DomainId Filter by domain ID .PARAMETER ProjectId Filter by project ID (-1 for all projects) .PARAMETER DisplayVolume Filter by whether the volume is displayed to the end user (root admin only) .PARAMETER IsEncrypted Filter by whether the volume is encrypted .PARAMETER IsRecursive With -DomainId, also include volumes in subdomains .PARAMETER ListAll List every volume the caller is allowed to see .PARAMETER ListSystemVMs Include volumes that belong to system VMs (root admin only) .PARAMETER Page Page number of results to return .PARAMETER PageSize Number of results per page .EXAMPLE Get-CSVolume Lists every volume in your account. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume Lists the volumes attached to a VM. .EXAMPLE Get-CSVolume -Type DATADISK -State Ready -ListAll | Where-Object { -not $_.virtualmachineid } Finds data disks that are not attached to any VM. .EXAMPLE Get-CSVolume -Tags @{ environment = 'production' } Lists volumes tagged environment=production. #> [CmdletBinding()] param( [string]$Id, [string[]]$Ids, [string]$Name, [string]$Keyword, [Parameter(ValueFromPipeline = $true)] [object]$VM, [string]$VirtualMachineId, [ValidateSet('ROOT', 'DATADISK')] [string]$Type, [ValidateSet('Ready', 'Allocated', 'Destroy', 'Expunging', 'Expunged')] [string]$State, [string]$ZoneId, [string]$PodId, [string]$ClusterId, [string]$HostId, [string]$StorageId, [string]$DiskOfferingId, [string]$ServiceOfferingId, [hashtable]$Tags, [string]$Account, [string]$DomainId, [string]$ProjectId, [bool]$DisplayVolume, [bool]$IsEncrypted, [switch]$IsRecursive, [switch]$ListAll, [switch]$ListSystemVMs, [int]$Page, [int]$PageSize ) process { if ($PSBoundParameters.ContainsKey('Id') -and $PSBoundParameters.ContainsKey('Ids')) { throw 'Specify either -Id or -Ids, not both.' } if ($PSBoundParameters.ContainsKey('Account') -and -not $PSBoundParameters.ContainsKey('DomainId')) { throw 'DomainId is required when Account is specified.' } $apiParams = @{} Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Id = 'id'; Ids = 'ids'; Name = 'name'; Keyword = 'keyword'; VirtualMachineId = 'virtualmachineid' Type = 'type'; State = 'state'; ZoneId = 'zoneid'; PodId = 'podid'; ClusterId = 'clusterid' HostId = 'hostid'; StorageId = 'storageid'; DiskOfferingId = 'diskofferingid' ServiceOfferingId = 'serviceofferingid'; Account = 'account'; DomainId = 'domainid' ProjectId = 'projectid'; DisplayVolume = 'displayvolume'; IsEncrypted = 'isencrypted' IsRecursive = 'isrecursive'; ListAll = 'listall'; ListSystemVMs = 'listsystemvms' Page = 'page'; PageSize = 'pagesize' }) if ($PSBoundParameters.ContainsKey('VM')) { if ($PSBoundParameters.ContainsKey('VirtualMachineId')) { throw 'Specify either -VM or -VirtualMachineId, not both.' } $apiParams['virtualmachineid'] = Resolve-CSVMTagId -VM $VM } Add-CSMapParameter -ApiParameters $apiParams -Name 'tags' -Map $Tags -KeyField 'key' -ValueField 'value' ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listVolumes' -Parameters $apiParams) -Command 'listVolumes' } } function New-CSVolume { <# .SYNOPSIS Creates a disk volume. .DESCRIPTION Creates a DATA volume (createVolume) from a disk offering or from a volume snapshot. A volume created from a disk offering is left detached unless -VirtualMachineId/-VM is given; attach it later with Mount-CSVolume. This is an asynchronous job; use -Wait to get the new volume back instead of the job handle. .PARAMETER Name The name of the volume .PARAMETER DiskOfferingId The disk offering to create the volume from. Either a disk offering or -SnapshotId is required. Mutually exclusive with -DiskOfferingName. .PARAMETER DiskOfferingName The exact name of the disk offering. Mutually exclusive with -DiskOfferingId. .PARAMETER SnapshotId The volume snapshot to create the volume from .PARAMETER ZoneId The zone to create the volume in. Mutually exclusive with -ZoneName. .PARAMETER ZoneName The exact name of the zone. Mutually exclusive with -ZoneId. .PARAMETER Size Size in GB. Required when the disk offering is a custom-size offering. .PARAMETER MinIops Minimum IOPS (custom-IOPS disk offerings) .PARAMETER MaxIops Maximum IOPS (custom-IOPS disk offerings) .PARAMETER VirtualMachineId Attach the new volume to this VM once it has been created .PARAMETER VM A VM name or VM object to attach the new volume to. Alternative to -VirtualMachineId. .PARAMETER DisplayVolume Whether to display the volume to the end user .PARAMETER Account Account that will own the volume. Must be used with -DomainId. .PARAMETER DomainId Domain of the owning account .PARAMETER ProjectId Project that will own the volume. Mutually exclusive with -Account. .PARAMETER CustomId A custom UUID for the volume (root admin only) .PARAMETER Wait Wait for the async job to finish and return the new volume .EXAMPLE New-CSVolume -Name 'web-01-data' -DiskOfferingName '100GB Standard' -ZoneName 'us-east-1' -Wait Creates a 100 GB data volume and returns it once it exists. .EXAMPLE New-CSVolume -Name 'scratch' -DiskOfferingName 'Custom' -Size 250 -ZoneName 'us-east-1' -VM 'web-01' -Wait Creates a 250 GB volume from a custom-size offering and attaches it to web-01. .EXAMPLE New-CSVolume -Name 'restored-data' -SnapshotId snap-uuid -Wait | Mount-CSVolume -VM 'web-01' -Wait Recreates a volume from a snapshot, then attaches it to a VM. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] param( [string]$Name, [string]$DiskOfferingId, [string]$DiskOfferingName, [string]$SnapshotId, [string]$ZoneId, [string]$ZoneName, [long]$Size, [long]$MinIops, [long]$MaxIops, [string]$VirtualMachineId, [object]$VM, [bool]$DisplayVolume, [string]$Account, [string]$DomainId, [string]$ProjectId, [string]$CustomId, [switch]$Wait ) if ($PSBoundParameters.ContainsKey('Account') -and -not $PSBoundParameters.ContainsKey('DomainId')) { throw 'DomainId is required when Account is specified.' } if ($PSBoundParameters.ContainsKey('Account') -and $PSBoundParameters.ContainsKey('ProjectId')) { throw 'Specify either -Account or -ProjectId, not both.' } if ($PSBoundParameters.ContainsKey('VM') -and $PSBoundParameters.ContainsKey('VirtualMachineId')) { throw 'Specify either -VM or -VirtualMachineId, not both.' } $resolvedDiskOfferingId = Resolve-CSObjectId -Id $DiskOfferingId -Name $DiskOfferingName ` -TypeName 'disk offering' -IdParameter 'DiskOfferingId' -NameParameter 'DiskOfferingName' ` -Lookup { param($lookupName) Get-CSDiskOffering -Name $lookupName } if (-not $resolvedDiskOfferingId -and -not $PSBoundParameters.ContainsKey('SnapshotId')) { throw 'A disk offering (-DiskOfferingId/-DiskOfferingName) or -SnapshotId is required.' } $resolvedZoneId = Resolve-CSObjectId -Id $ZoneId -Name $ZoneName ` -TypeName 'zone' -IdParameter 'ZoneId' -NameParameter 'ZoneName' ` -Lookup { param($lookupName) Get-CSZone -Name $lookupName } $apiParams = @{} if ($resolvedDiskOfferingId) { $apiParams['diskofferingid'] = $resolvedDiskOfferingId } if ($resolvedZoneId) { $apiParams['zoneid'] = $resolvedZoneId } if ($PSBoundParameters.ContainsKey('VM')) { $apiParams['virtualmachineid'] = Resolve-CSVMTagId -VM $VM } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Name = 'name'; SnapshotId = 'snapshotid'; Size = 'size'; MinIops = 'miniops'; MaxIops = 'maxiops' VirtualMachineId = 'virtualmachineid'; DisplayVolume = 'displayvolume'; Account = 'account' DomainId = 'domainid'; ProjectId = 'projectid'; CustomId = 'customid' }) $target = if ($Name) { "volume $Name" } else { 'volume' } if ($PSCmdlet.ShouldProcess($target, 'Create')) { Invoke-CSAsyncApiRequest -Command 'createVolume' -Parameters $apiParams -Wait:$Wait } } function Remove-CSVolume { <# .SYNOPSIS Destroys a volume. .DESCRIPTION Destroys a volume (destroyVolume). Like Remove-CSVM, a destroyed volume can be brought back with Restore-CSDestroyedVolume until it is expunged; add -Expunge to remove it permanently in one step. Use Clear-CSVolume (deleteVolume) to delete a detached volume outright. This is an asynchronous job; use -Wait to block until it finishes. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to destroy (binds from a piped volume's id) .PARAMETER Expunge Expunge the volume immediately instead of leaving it recoverable .PARAMETER Wait Wait for the async job to finish and return its result .EXAMPLE Remove-CSVolume -Id vol-uuid Destroys a volume after prompting for confirmation. It stays recoverable until the storage cleanup interval expunges it. .EXAMPLE Get-CSVolume -Keyword 'scratch-' -Type DATADISK | Remove-CSVolume -Expunge -Confirm:$false Permanently removes every scratch data volume without prompting. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [switch]$Expunge, [switch]$Wait ) process { $apiParams = @{ id = $Id } if ($Expunge) { $apiParams['expunge'] = 'true' } $action = if ($Expunge) { 'Destroy and expunge' } else { 'Destroy' } if ($PSCmdlet.ShouldProcess("volume $Id", $action)) { Invoke-CSAsyncApiRequest -Command 'destroyVolume' -Parameters $apiParams -Wait:$Wait } } } function Clear-CSVolume { <# .SYNOPSIS Deletes a detached volume permanently. .DESCRIPTION Deletes a detached disk volume (deleteVolume). Unlike Remove-CSVolume (destroyVolume), this cannot be undone with Restore-CSDestroyedVolume. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to delete (binds from a piped volume's id) .EXAMPLE Clear-CSVolume -Id vol-uuid Permanently deletes a detached volume after prompting for confirmation. .EXAMPLE Get-CSVolume -State Destroy -ListAll | Clear-CSVolume -Confirm:$false Permanently deletes every already-destroyed volume. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id ) process { if ($PSCmdlet.ShouldProcess("volume $Id", 'Delete permanently')) { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'deleteVolume' -Parameters @{ id = $Id }) -Command 'deleteVolume' } } } function Restore-CSDestroyedVolume { <# .SYNOPSIS Recovers a destroyed volume. .DESCRIPTION Recovers a volume in the Destroy state (recoverVolume) that has not yet been expunged. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to recover (binds from a piped volume's id) .EXAMPLE Restore-CSDestroyedVolume -Id vol-uuid Recovers a destroyed volume. .EXAMPLE Get-CSVolume -Name 'web-01-data' -State Destroy | Restore-CSDestroyedVolume Recovers a destroyed volume found by name. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id ) process { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'recoverVolume' -Parameters @{ id = $Id }) -Command 'recoverVolume' } } function Mount-CSVolume { <# .SYNOPSIS Attaches a volume to a virtual machine. .DESCRIPTION Attaches a disk volume to a VM (attachVolume). The VM can be given by ID, name, or object. This is an asynchronous job; use -Wait to get the attached volume back. Accepts volume objects from Get-CSVolume or New-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to attach (binds from a piped volume's id) .PARAMETER VirtualMachineId The ID of the VM to attach the volume to .PARAMETER VM A VM name or VM object to attach the volume to. Alternative to -VirtualMachineId. .PARAMETER DeviceId The device ID in the guest. Defaults to the next free slot; 0 attaches the volume as the ROOT disk. .PARAMETER Wait Wait for the async job to finish and return the attached volume .EXAMPLE Mount-CSVolume -Id vol-uuid -VM 'web-01' -Wait Attaches a volume to a VM found by name and waits for the result. .EXAMPLE Get-CSVolume -Name 'web-01-data' | Mount-CSVolume -VirtualMachineId vm-uuid Attaches a volume found by name to a VM. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [string]$VirtualMachineId, [object]$VM, [long]$DeviceId, [switch]$Wait ) process { if ($PSBoundParameters.ContainsKey('VM') -and $PSBoundParameters.ContainsKey('VirtualMachineId')) { throw 'Specify either -VM or -VirtualMachineId, not both.' } $resolvedVmId = Resolve-CSVMTagId -VirtualMachineId $VirtualMachineId -VM $VM $apiParams = @{ id = $Id; virtualmachineid = $resolvedVmId } if ($PSBoundParameters.ContainsKey('DeviceId')) { $apiParams['deviceid'] = $DeviceId } if ($PSCmdlet.ShouldProcess("volume $Id", "Attach to VM $resolvedVmId")) { Invoke-CSAsyncApiRequest -Command 'attachVolume' -Parameters $apiParams -Wait:$Wait } } } function Dismount-CSVolume { <# .SYNOPSIS Detaches a volume from a virtual machine. .DESCRIPTION Detaches a disk volume (detachVolume), identified either by its volume ID or by the VM and device ID it is attached at. This is an asynchronous job; use -Wait to get the detached volume back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to detach (binds from a piped volume's id) .PARAMETER VirtualMachineId The VM to detach from, used together with -DeviceId .PARAMETER VM A VM name or VM object to detach from, used together with -DeviceId .PARAMETER DeviceId The device ID of the volume on the VM .PARAMETER Wait Wait for the async job to finish and return the detached volume .EXAMPLE Dismount-CSVolume -Id vol-uuid -Wait Detaches a volume and waits for the result. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume -Type DATADISK | Dismount-CSVolume -Confirm:$false Detaches every data disk from a VM. .EXAMPLE Dismount-CSVolume -VM 'web-01' -DeviceId 1 Detaches whatever volume is attached at device 1 on web-01. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ById')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = 'ById')] [Alias('VolumeId')] [string]$Id, [Parameter(ParameterSetName = 'ByDevice')] [string]$VirtualMachineId, [Parameter(ParameterSetName = 'ByDevice')] [object]$VM, [Parameter(Mandatory = $true, ParameterSetName = 'ByDevice')] [long]$DeviceId, [switch]$Wait ) process { if ($PSCmdlet.ParameterSetName -eq 'ById') { $apiParams = @{ id = $Id } $target = "volume $Id" } else { if ($PSBoundParameters.ContainsKey('VM') -and $PSBoundParameters.ContainsKey('VirtualMachineId')) { throw 'Specify either -VM or -VirtualMachineId, not both.' } $resolvedVmId = Resolve-CSVMTagId -VirtualMachineId $VirtualMachineId -VM $VM $apiParams = @{ virtualmachineid = $resolvedVmId; deviceid = $DeviceId } $target = "device $DeviceId on VM $resolvedVmId" } if ($PSCmdlet.ShouldProcess($target, 'Detach volume')) { Invoke-CSAsyncApiRequest -Command 'detachVolume' -Parameters $apiParams -Wait:$Wait } } } function Resize-CSVolume { <# .SYNOPSIS Resizes a volume. .DESCRIPTION Resizes a volume (resizeVolume), either to a new size on a custom-size offering or by switching to a different disk offering. Shrinking requires -ShrinkOk. This is an asynchronous job; use -Wait to get the resized volume back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to resize (binds from a piped volume's id) .PARAMETER Size The new size in GB .PARAMETER DiskOfferingId A new disk offering to resize to. Mutually exclusive with -DiskOfferingName. .PARAMETER DiskOfferingName The exact name of the new disk offering. Mutually exclusive with -DiskOfferingId. .PARAMETER MinIops New minimum IOPS (custom-IOPS offerings) .PARAMETER MaxIops New maximum IOPS (custom-IOPS offerings) .PARAMETER ShrinkOk Allow the volume to shrink. Data past the new size is lost. .PARAMETER Wait Wait for the async job to finish and return the resized volume .EXAMPLE Resize-CSVolume -Id vol-uuid -Size 200 -Wait Grows a custom-size volume to 200 GB. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume -Type ROOT | Resize-CSVolume -Size 80 Grows a VM's root disk to 80 GB. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [long]$Size, [string]$DiskOfferingId, [string]$DiskOfferingName, [long]$MinIops, [long]$MaxIops, [switch]$ShrinkOk, [switch]$Wait ) process { $resolvedDiskOfferingId = Resolve-CSObjectId -Id $DiskOfferingId -Name $DiskOfferingName ` -TypeName 'disk offering' -IdParameter 'DiskOfferingId' -NameParameter 'DiskOfferingName' ` -Lookup { param($lookupName) Get-CSDiskOffering -Name $lookupName } if (-not $resolvedDiskOfferingId -and -not $PSBoundParameters.ContainsKey('Size') -and -not $PSBoundParameters.ContainsKey('MinIops') -and -not $PSBoundParameters.ContainsKey('MaxIops')) { throw 'Specify a new -Size, a new disk offering, or new IOPS limits.' } $apiParams = @{ id = $Id } if ($resolvedDiskOfferingId) { $apiParams['diskofferingid'] = $resolvedDiskOfferingId } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Size = 'size'; MinIops = 'miniops'; MaxIops = 'maxiops'; ShrinkOk = 'shrinkok' }) $description = if ($PSBoundParameters.ContainsKey('Size')) { "Resize to $Size GB" } else { 'Resize' } if ($PSCmdlet.ShouldProcess("volume $Id", $description)) { Invoke-CSAsyncApiRequest -Command 'resizeVolume' -Parameters $apiParams -Wait:$Wait } } } function Set-CSVolumeDiskOffering { <# .SYNOPSIS Changes a volume's disk offering. .DESCRIPTION Moves a volume to a different disk offering (changeOfferingForVolume), optionally migrating it to a storage pool that satisfies the new offering. This is an asynchronous job; use -Wait to get the updated volume back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume (binds from a piped volume's id) .PARAMETER DiskOfferingId The new disk offering. Mutually exclusive with -DiskOfferingName; one is required. .PARAMETER DiskOfferingName The exact name of the new disk offering. Mutually exclusive with -DiskOfferingId. .PARAMETER Size New size in GB (custom-size offerings) .PARAMETER MinIops New minimum IOPS (custom-IOPS offerings) .PARAMETER MaxIops New maximum IOPS (custom-IOPS offerings) .PARAMETER AutoMigrate Migrate the volume automatically if its current pool does not suit the new offering .PARAMETER ShrinkOk Allow the volume to shrink .PARAMETER Wait Wait for the async job to finish and return the updated volume .EXAMPLE Set-CSVolumeDiskOffering -Id vol-uuid -DiskOfferingName 'Premium SSD' -AutoMigrate -Wait Moves a volume to a faster offering, migrating it if necessary. .EXAMPLE Get-CSVolume -DiskOfferingId old-offering-uuid -ListAll | Set-CSVolumeDiskOffering -DiskOfferingId new-offering-uuid Moves every volume off a retired disk offering. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [string]$DiskOfferingId, [string]$DiskOfferingName, [long]$Size, [long]$MinIops, [long]$MaxIops, [switch]$AutoMigrate, [switch]$ShrinkOk, [switch]$Wait ) begin { # Resolve once: every piped volume moves to the same offering. $resolvedDiskOfferingId = Resolve-CSObjectId -Id $DiskOfferingId -Name $DiskOfferingName -Required ` -TypeName 'disk offering' -IdParameter 'DiskOfferingId' -NameParameter 'DiskOfferingName' ` -Lookup { param($lookupName) Get-CSDiskOffering -Name $lookupName } } process { $apiParams = @{ id = $Id; diskofferingid = $resolvedDiskOfferingId } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Size = 'size'; MinIops = 'miniops'; MaxIops = 'maxiops'; AutoMigrate = 'automigrate'; ShrinkOk = 'shrinkok' }) if ($PSCmdlet.ShouldProcess("volume $Id", "Change disk offering to $resolvedDiskOfferingId")) { Invoke-CSAsyncApiRequest -Command 'changeOfferingForVolume' -Parameters $apiParams -Wait:$Wait } } } function Move-CSVolume { <# .SYNOPSIS Migrates a volume to another primary storage pool. .DESCRIPTION Migrates a volume (migrateVolume) to a different storage pool. A volume attached to a running VM needs -LiveMigrate. This is an asynchronous job; use -Wait to get the migrated volume back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to migrate (binds from a piped volume's id) .PARAMETER StorageId The destination storage pool ID. Never bound from the pipeline, because a piped volume's own storageid is its current pool. .PARAMETER LiveMigrate Live-migrate a volume that is attached to a running VM .PARAMETER NewDiskOfferingId A disk offering to switch the volume to as part of the migration .PARAMETER Wait Wait for the async job to finish and return the migrated volume .EXAMPLE Move-CSVolume -Id vol-uuid -StorageId pool-uuid -Wait Migrates a detached volume to another pool. .EXAMPLE Get-CSVolume -StorageId old-pool-uuid -ListAll | Move-CSVolume -StorageId new-pool-uuid -LiveMigrate Evacuates every volume from a storage pool, live-migrating attached ones. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [Parameter(Mandatory = $true)] [string]$StorageId, [switch]$LiveMigrate, [string]$NewDiskOfferingId, [switch]$Wait ) process { $apiParams = @{ volumeid = $Id; storageid = $StorageId } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ LiveMigrate = 'livemigrate'; NewDiskOfferingId = 'newdiskofferingid' }) if ($PSCmdlet.ShouldProcess("volume $Id", "Migrate to storage pool $StorageId")) { Invoke-CSAsyncApiRequest -Command 'migrateVolume' -Parameters $apiParams -Wait:$Wait } } } function Set-CSVolume { <# .SYNOPSIS Updates a volume's properties. .DESCRIPTION Updates a volume (updateVolume): rename it, hide it from end users, or protect it from deletion. -Path, -State, -StorageId and -ChainInfo change CloudStack's record of where the volume lives and are meant for admins repairing the database. This is an asynchronous job; use -Wait to get the updated volume back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to update (binds from a piped volume's id) .PARAMETER Name A new name for the volume .PARAMETER DisplayVolume Whether to display the volume to the end user .PARAMETER DeleteProtection Protect the volume from deletion. Ignored for volumes managed by autoscale or CKS. .PARAMETER CustomId A custom UUID for the volume (root admin only) .PARAMETER Path The volume's path on primary storage (admin repair) .PARAMETER State The volume's state (admin repair) .PARAMETER StorageId The UUID of the storage pool the volume is on (admin repair). Never bound from the pipeline. .PARAMETER ChainInfo The volume's chain info (admin repair) .PARAMETER Wait Wait for the async job to finish and return the updated volume .EXAMPLE Set-CSVolume -Id vol-uuid -Name 'web-01-data' Renames a volume. .EXAMPLE Get-CSVM -Name 'db-01' | Get-CSVolume | Set-CSVolume -DeleteProtection $true -Wait Turns on delete protection for every volume on a VM. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [string]$Name, [bool]$DisplayVolume, [bool]$DeleteProtection, [string]$CustomId, [string]$Path, [string]$State, [string]$StorageId, [string]$ChainInfo, [switch]$Wait ) process { $apiParams = @{ id = $Id } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Name = 'name'; DisplayVolume = 'displayvolume'; DeleteProtection = 'deleteprotection' CustomId = 'customid'; Path = 'path'; State = 'state'; StorageId = 'storageid'; ChainInfo = 'chaininfo' }) if ($apiParams.Count -eq 1) { throw 'Specify at least one property to update.' } if ($PSCmdlet.ShouldProcess("volume $Id", 'Update')) { Invoke-CSAsyncApiRequest -Command 'updateVolume' -Parameters $apiParams -Wait:$Wait } } } function Set-CSVolumeOwner { <# .SYNOPSIS Changes the owner of a volume. .DESCRIPTION Reassigns a volume to another account or project (assignVolume). Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume (binds from a piped volume's id) .PARAMETER AccountId The ID of the account to give the volume to. Mutually exclusive with -ProjectId. .PARAMETER ProjectId The ID of the project to give the volume to. Mutually exclusive with -AccountId. .EXAMPLE Set-CSVolumeOwner -Id vol-uuid -AccountId account-uuid Gives a volume to another account. .EXAMPLE Get-CSVolume -Name 'shared-data' | Set-CSVolumeOwner -ProjectId project-uuid Moves a volume found by name into a project. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [string]$AccountId, [string]$ProjectId ) process { $hasAccount = $PSBoundParameters.ContainsKey('AccountId') $hasProject = $PSBoundParameters.ContainsKey('ProjectId') if ($hasAccount -eq $hasProject) { throw 'Specify exactly one of -AccountId or -ProjectId.' } $apiParams = @{ volumeid = $Id } if ($hasAccount) { $apiParams['accountid'] = $AccountId; $newOwner = "account $AccountId" } else { $apiParams['projectid'] = $ProjectId; $newOwner = "project $ProjectId" } if ($PSCmdlet.ShouldProcess("volume $Id", "Assign to $newOwner")) { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'assignVolume' -Parameters $apiParams) -Command 'assignVolume' } } } function Test-CSVolume { <# .SYNOPSIS Checks a volume for errors and leaks, optionally repairing them. .DESCRIPTION Runs a consistency check on a volume (checkVolume). KVM only; the volume must be detached or its VM stopped. With -Repair, CloudStack also fixes what it finds. This is an asynchronous job; use -Wait to get the check result back. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to check (binds from a piped volume's id) .PARAMETER Repair Repair what the check finds: 'leaks' for leaked clusters only, 'all' for every error .PARAMETER Wait Wait for the async job to finish and return the result .EXAMPLE Test-CSVolume -Id vol-uuid -Wait Checks a volume and returns the result. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume | Test-CSVolume -Repair leaks -Wait Checks every disk of a stopped VM and repairs leaked clusters. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [ValidateSet('leaks', 'all')] [string]$Repair, [switch]$Wait ) process { $apiParams = @{ id = $Id } if ($PSBoundParameters.ContainsKey('Repair')) { $apiParams['repair'] = $Repair } # A read-only check needs no confirmation; only a repair changes the disk. if (-not $Repair -or $PSCmdlet.ShouldProcess("volume $Id", "Check and repair ($Repair)")) { Invoke-CSAsyncApiRequest -Command 'checkVolume' -Parameters $apiParams -Wait:$Wait } } } function Export-CSVolume { <# .SYNOPSIS Extracts a volume for download or upload. .DESCRIPTION Extracts a volume (extractVolume). HTTP_DOWNLOAD produces a download URL; FTP_UPLOAD pushes the volume to -Url. This is an asynchronous job; use -Wait to get the extract result, which carries the download URL. Accepts volume objects from Get-CSVolume on the pipeline; the volume's zone binds to -ZoneId automatically. .PARAMETER Id The ID of the volume to extract (binds from a piped volume's id) .PARAMETER ZoneId The zone the volume is in (binds from a piped volume's zoneid) .PARAMETER Mode HTTP_DOWNLOAD or FTP_UPLOAD .PARAMETER Url Destination URL. Required for FTP_UPLOAD. .PARAMETER Wait Wait for the async job to finish and return the extract result .EXAMPLE (Export-CSVolume -Id vol-uuid -ZoneId zone-uuid -Mode HTTP_DOWNLOAD -Wait).url Gets a download URL for a volume. .EXAMPLE Get-CSVolume -Name 'web-01-data' | Export-CSVolume -Mode HTTP_DOWNLOAD -Wait Extracts a volume found by name; its zone comes from the volume object. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$ZoneId, [Parameter(Mandatory = $true)] [ValidateSet('HTTP_DOWNLOAD', 'FTP_UPLOAD')] [string]$Mode, [string]$Url, [switch]$Wait ) process { if ($Mode -eq 'FTP_UPLOAD' -and -not $PSBoundParameters.ContainsKey('Url')) { throw 'Url is required when Mode is FTP_UPLOAD.' } $apiParams = @{ id = $Id; zoneid = $ZoneId; mode = $Mode } if ($PSBoundParameters.ContainsKey('Url')) { $apiParams['url'] = $Url } Invoke-CSAsyncApiRequest -Command 'extractVolume' -Parameters $apiParams -Wait:$Wait } } function Get-CSVolumePath { <# .SYNOPSIS Gets a volume's path on primary storage. .DESCRIPTION Returns the storage path CloudStack has recorded for a volume (getPathForVolume). Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume (binds from a piped volume's id) .EXAMPLE Get-CSVolumePath -Id vol-uuid Returns the volume's storage path. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume | Get-CSVolumePath Returns the storage path of every disk on a VM. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id ) process { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'getPathForVolume' -Parameters @{ volumeid = $Id }) -Command 'getPathForVolume' } } function Get-CSVolumeIscsiName { <# .SYNOPSIS Gets a volume's iSCSI name. .DESCRIPTION Returns the iSCSI name (IQN) of a volume on managed storage (getVolumeiScsiName). Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume (binds from a piped volume's id) .EXAMPLE Get-CSVolumeIscsiName -Id vol-uuid Returns the volume's iSCSI name. .EXAMPLE Get-CSVolume -StorageId solidfire-pool-uuid -ListAll | Get-CSVolumeIscsiName Returns the iSCSI name of every volume on a managed storage pool. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id ) process { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'getVolumeiScsiName' -Parameters @{ volumeid = $Id }) -Command 'getVolumeiScsiName' } } function Get-CSVolumeUsageHistory { <# .SYNOPSIS Lists volume usage-history statistics. .DESCRIPTION Returns the stats CloudStack has collected for volumes (listVolumesUsageHistory). Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume (binds from a piped volume's id) .PARAMETER Ids Several volume IDs. Mutually exclusive with -Id. .PARAMETER Name Filter by volume name (substring match) .PARAMETER Keyword Filter by keyword .PARAMETER StartDate Start of the period, "yyyy-MM-dd HH:mm:ss" .PARAMETER EndDate End of the period, "yyyy-MM-dd HH:mm:ss" .PARAMETER Page Page number of results to return .PARAMETER PageSize Number of results per page .EXAMPLE Get-CSVolumeUsageHistory -Id vol-uuid -StartDate '2026-09-01 00:00:00' Returns a volume's stats since the start of September. .EXAMPLE Get-CSVM -Name 'db-01' | Get-CSVolume | Get-CSVolumeUsageHistory Returns the stats for every disk on a VM. #> [CmdletBinding()] param( [Parameter(ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [string[]]$Ids, [string]$Name, [string]$Keyword, [string]$StartDate, [string]$EndDate, [int]$Page, [int]$PageSize ) process { if ($PSBoundParameters.ContainsKey('Id') -and $PSBoundParameters.ContainsKey('Ids')) { throw 'Specify either -Id or -Ids, not both.' } $apiParams = @{} Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Id = 'id'; Ids = 'ids'; Name = 'name'; Keyword = 'keyword'; StartDate = 'startdate'; EndDate = 'enddate' Page = 'page'; PageSize = 'pagesize' }) ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listVolumesUsageHistory' -Parameters $apiParams) -Command 'listVolumesUsageHistory' } } function Get-CSVolumeUploadParams { <# .SYNOPSIS Gets the signed parameters for uploading a data disk from your machine. .DESCRIPTION Returns CloudStack's POST URL, signature, metadata, expiry and the new volume's ID (getUploadParamsForVolume). You still have to POST the disk image to the returned URL yourself. To have CloudStack fetch an image from a web server instead, use Import-CSVolumeFromUrl. .PARAMETER Name The name of the new volume .PARAMETER ZoneId The zone to create the volume in. Mutually exclusive with -ZoneName. .PARAMETER ZoneName The exact name of the zone. Mutually exclusive with -ZoneId. .PARAMETER Format Disk image format: QCOW2, OVA, or VHD .PARAMETER DiskOfferingId A custom-size disk offering to associate with the volume .PARAMETER Checksum Checksum of the image. MD5 by default; prefix others, e.g. '{SHA-256}<hex>'. .PARAMETER ImageStoreUuid The image store to upload to .PARAMETER Account Account that will own the volume. Must be used with -DomainId. .PARAMETER DomainId Domain of the owning account .PARAMETER ProjectId Project that will own the volume .EXAMPLE $upload = Get-CSVolumeUploadParams -Name 'imported-data' -ZoneName 'us-east-1' -Format QCOW2 Gets the upload URL and signature for a QCOW2 data disk. #> [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string]$Name, [string]$ZoneId, [string]$ZoneName, [Parameter(Mandatory = $true)] [ValidateSet('QCOW2', 'OVA', 'VHD')] [string]$Format, [string]$DiskOfferingId, [string]$Checksum, [string]$ImageStoreUuid, [string]$Account, [string]$DomainId, [string]$ProjectId ) if ($PSBoundParameters.ContainsKey('Account') -and -not $PSBoundParameters.ContainsKey('DomainId')) { throw 'DomainId is required when Account is specified.' } $resolvedZoneId = Resolve-CSObjectId -Id $ZoneId -Name $ZoneName -Required ` -TypeName 'zone' -IdParameter 'ZoneId' -NameParameter 'ZoneName' ` -Lookup { param($lookupName) Get-CSZone -Name $lookupName } $apiParams = @{ name = $Name; zoneid = $resolvedZoneId; format = $Format } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ DiskOfferingId = 'diskofferingid'; Checksum = 'checksum'; ImageStoreUuid = 'imagestoreuuid' Account = 'account'; DomainId = 'domainid'; ProjectId = 'projectid' }) ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'getUploadParamsForVolume' -Parameters $apiParams) -Command 'getUploadParamsForVolume' } function Import-CSVolumeFromUrl { <# .SYNOPSIS Creates a data volume from a disk image hosted on a web server. .DESCRIPTION Has CloudStack download a disk image from an http(s) URL into a new data volume (uploadVolume). The volume is created detached; attach it with Mount-CSVolume once its state is Uploaded/Ready. This is an asynchronous job; use -Wait to get the new volume back. .PARAMETER Name The name of the new volume .PARAMETER Url The http:// or https:// URL of the disk image .PARAMETER ZoneId The zone to create the volume in. Mutually exclusive with -ZoneName. .PARAMETER ZoneName The exact name of the zone. Mutually exclusive with -ZoneId. .PARAMETER Format Disk image format: QCOW2, OVA, or VHD .PARAMETER DiskOfferingId A custom-size disk offering to associate with the volume .PARAMETER Checksum Checksum of the image. MD5 by default; prefix others, e.g. '{SHA-256}<hex>'. .PARAMETER ImageStoreUuid The image store to download to .PARAMETER Account Account that will own the volume. Must be used with -DomainId. .PARAMETER DomainId Domain of the owning account .PARAMETER ProjectId Project that will own the volume .PARAMETER Wait Wait for the async job to finish and return the new volume .EXAMPLE Import-CSVolumeFromUrl -Name 'dataset' -Url 'https://images.example.com/dataset.qcow2' -Format QCOW2 -ZoneName 'us-east-1' -Wait Creates a volume from a QCOW2 image on a web server. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string]$Url, [string]$ZoneId, [string]$ZoneName, [Parameter(Mandatory = $true)] [ValidateSet('QCOW2', 'OVA', 'VHD')] [string]$Format, [string]$DiskOfferingId, [string]$Checksum, [string]$ImageStoreUuid, [string]$Account, [string]$DomainId, [string]$ProjectId, [switch]$Wait ) if ($PSBoundParameters.ContainsKey('Account') -and -not $PSBoundParameters.ContainsKey('DomainId')) { throw 'DomainId is required when Account is specified.' } $resolvedZoneId = Resolve-CSObjectId -Id $ZoneId -Name $ZoneName -Required ` -TypeName 'zone' -IdParameter 'ZoneId' -NameParameter 'ZoneName' ` -Lookup { param($lookupName) Get-CSZone -Name $lookupName } $apiParams = @{ name = $Name; url = $Url; zoneid = $resolvedZoneId; format = $Format } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ DiskOfferingId = 'diskofferingid'; Checksum = 'checksum'; ImageStoreUuid = 'imagestoreuuid' Account = 'account'; DomainId = 'domainid'; ProjectId = 'projectid' }) if ($PSCmdlet.ShouldProcess("volume $Name", "Upload from $Url")) { Invoke-CSAsyncApiRequest -Command 'uploadVolume' -Parameters $apiParams -Wait:$Wait } } function Get-CSVolumeForImport { <# .SYNOPSIS Lists unmanaged volumes on a storage pool. .DESCRIPTION Lists disks on a primary storage pool that CloudStack does not manage yet (listVolumesForImport). Pipe the results to Import-CSVolume to bring them under management. .PARAMETER StorageId The storage pool to scan (required; binds from a piped storage pool's id) .PARAMETER Path Only return the volume at this path .PARAMETER Keyword Filter by keyword .PARAMETER Page Page number of results to return .PARAMETER PageSize Number of results per page .EXAMPLE Get-CSVolumeForImport -StorageId pool-uuid Lists the unmanaged disks on a storage pool. .EXAMPLE Get-CSVolumeForImport -StorageId pool-uuid -Keyword 'legacy' | Import-CSVolume -DiskOfferingId offering-uuid -Wait Imports every unmanaged disk whose name contains 'legacy'. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('Id')] [string]$StorageId, [string]$Path, [string]$Keyword, [int]$Page, [int]$PageSize ) process { $apiParams = @{ storageid = $StorageId } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Path = 'path'; Keyword = 'keyword'; Page = 'page'; PageSize = 'pagesize' }) ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listVolumesForImport' -Parameters $apiParams) -Command 'listVolumesForImport' } } function Import-CSVolume { <# .SYNOPSIS Brings an unmanaged volume on a storage pool under CloudStack management. .DESCRIPTION Imports an existing disk from a primary storage pool (importVolume). The inverse of Unregister-CSVolume. Accepts objects from Get-CSVolumeForImport on the pipeline; their path and storageid bind automatically. This is an asynchronous job; use -Wait to get the imported volume back. .PARAMETER Path The path of the disk on the storage pool (binds from a piped object's path) .PARAMETER StorageId The storage pool holding the disk (binds from a piped object's storageid) .PARAMETER Name A name for the volume. Defaults to the path. .PARAMETER DiskOfferingId The disk offering to link the volume to .PARAMETER Account Account that will own the volume. Must be used with -DomainId. .PARAMETER DomainId Domain of the owning account .PARAMETER ProjectId Project that will own the volume .PARAMETER Wait Wait for the async job to finish and return the imported volume .EXAMPLE Import-CSVolume -StorageId pool-uuid -Path 'legacy-data.qcow2' -Name 'legacy-data' -Wait Imports one disk from a storage pool. .EXAMPLE Get-CSVolumeForImport -StorageId pool-uuid | Import-CSVolume -Account 'engineering' -DomainId domain-uuid Imports every unmanaged disk on a pool into an account. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$Path, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$StorageId, [string]$Name, [string]$DiskOfferingId, [string]$Account, [string]$DomainId, [string]$ProjectId, [switch]$Wait ) process { if ($PSBoundParameters.ContainsKey('Account') -and -not $PSBoundParameters.ContainsKey('DomainId')) { throw 'DomainId is required when Account is specified.' } $apiParams = @{ path = $Path; storageid = $StorageId } Add-CSOptionalParameter -ApiParameters $apiParams -BoundParameters $PSBoundParameters -Map ([ordered]@{ Name = 'name'; DiskOfferingId = 'diskofferingid'; Account = 'account'; DomainId = 'domainid'; ProjectId = 'projectid' }) if ($PSCmdlet.ShouldProcess("$Path on storage pool $StorageId", 'Import volume')) { Invoke-CSAsyncApiRequest -Command 'importVolume' -Parameters $apiParams -Wait:$Wait } } } function Unregister-CSVolume { <# .SYNOPSIS Removes a volume from CloudStack management without deleting the disk. .DESCRIPTION Unmanages a volume (unmanageVolume): CloudStack forgets it but the disk stays on the storage pool, where Get-CSVolumeForImport can find it again. This is an asynchronous job; use -Wait to block until it finishes. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the volume to unmanage (binds from a piped volume's id) .PARAMETER Wait Wait for the async job to finish and return its result .EXAMPLE Unregister-CSVolume -Id vol-uuid Unmanages a volume after prompting for confirmation. .EXAMPLE Get-CSVolume -Name 'legacy-data' | Unregister-CSVolume -Confirm:$false -Wait Unmanages a volume found by name without prompting. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'High')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [switch]$Wait ) process { if ($PSCmdlet.ShouldProcess("volume $Id", 'Unmanage')) { Invoke-CSAsyncApiRequest -Command 'unmanageVolume' -Parameters @{ id = $Id } -Wait:$Wait } } } function Restore-CSVolumeFromBackup { <# .SYNOPSIS Restores a single volume from a VM backup and attaches it to a VM. .DESCRIPTION Restores one backed-up volume and attaches it to a VM (restoreVolumeFromBackupAndAttachToVM). The VM can be given by ID, name, or object. This is an asynchronous job; use -Wait to block until it finishes. Accepts volume objects from Get-CSVolume on the pipeline. .PARAMETER Id The ID of the backed-up volume to restore (binds from a piped volume's id) .PARAMETER BackupId The ID of the VM backup to restore from .PARAMETER VirtualMachineId The VM to attach the restored volume to .PARAMETER VM A VM name or VM object to attach the restored volume to. Alternative to -VirtualMachineId. .PARAMETER Wait Wait for the async job to finish and return its result .EXAMPLE Restore-CSVolumeFromBackup -Id vol-uuid -BackupId backup-uuid -VM 'web-01' -Wait Restores a volume from a backup and attaches it to web-01. .EXAMPLE Get-CSVM -Name 'web-01' | Get-CSVolume -Type DATADISK | Restore-CSVolumeFromBackup -BackupId backup-uuid -VM 'web-01-restore' Restores each data disk of web-01 from a backup onto a recovery VM. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Alias('VolumeId')] [string]$Id, [Parameter(Mandatory = $true)] [string]$BackupId, [string]$VirtualMachineId, [object]$VM, [switch]$Wait ) begin { # Resolve once, rather than looking the VM up again for every piped volume. if ($PSBoundParameters.ContainsKey('VM') -and $PSBoundParameters.ContainsKey('VirtualMachineId')) { throw 'Specify either -VM or -VirtualMachineId, not both.' } $resolvedVmId = Resolve-CSVMTagId -VirtualMachineId $VirtualMachineId -VM $VM } process { $apiParams = @{ volumeid = $Id; backupid = $BackupId; virtualmachineid = $resolvedVmId } if ($PSCmdlet.ShouldProcess("volume $Id from backup $BackupId", "Restore and attach to VM $resolvedVmId")) { Invoke-CSAsyncApiRequest -Command 'restoreVolumeFromBackupAndAttachToVM' -Parameters $apiParams -Wait:$Wait } } } function Get-CSElastistorVolume { <# .SYNOPSIS Lists the volumes on a CloudByte ElastiStor account. .DESCRIPTION Wraps listElastistorVolume, which is only available when the ElastiStor storage plugin is installed. .PARAMETER Id The ElastiStor account ID (binds from a piped object's id) .EXAMPLE Get-CSElastistorVolume -Id elastistor-account-id Lists the volumes on an ElastiStor account. #> [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [string]$Id ) process { ConvertFrom-CSResponse -Response (Invoke-CSApiRequest -Command 'listElastistorVolume' -Parameters @{ id = $Id }) -Command 'listElastistorVolume' } } |