PowerCLI: Copy a vmdk from one VM to another
I created this script to help assist a customer automate an operation they perform regularly. Basically they restore a VM and then either attach directly to a vmdk in the restored VM or copy a vmdk into a folder of a target VM. This task is performed regularly and to reduce time and the risk of errors in attaching or moving the wrong vmdk they wanted a way to automate the process to be able to repeat the process quickly and accurately.
The script below will copy a virtual machine disk ($recoveryHD) from one VM ($Source) and then attach it to another VM ($Target).
There is a second snippet of Windows powershell code which sets the volume to read/write and mounts it in the target VM.
######################################################################################################## # PowerCLI script to copy a vmdk from one VM (a recovery VM) to another VM (the target VM) # Usage copy_recoveryVMDK.ps1 # # Requires active connection to vCenter Server (using Connect-VIServer) # # History: # 11/14/2015 - Hersey http://www.vhersey.com/ - Created # ######################################################################################################## #Variables # Recovery VM Inventory Name which contains the vmdk to copy $Source = "CLONELABFILE01" # Target VM Inventory Name where vmdk will be copied to $Target = "LABFILE01" # Define which Virtual Hard Disk is the vmdk to copy from Recovery VM to Target VM $recoveryHD = "Hard disk 3" Clear-Host Write-Host "Here. We. Go!" -ForeGroundColor Cyan #Get Working Directory of Target VM Write-Host "Determining Working Directory of Target VM ..." -ForeGroundColor Cyan $targetVM = Get-VM $Target $targetWORK = $targetVM | Get-HardDisk | Where {$_.Name -eq "Hard disk 1"} $targetDIR = $targetWORK.Filename.Split("/")[0] #Set location and name of new VMDK $dateTime = Get-Date -Format MMddyyhhmmss #Just an attempt to add some uniqueness to the vmdk file name. $NewVMDK = "$targetDIR/recovery-VM-$dateTime.vmdk" #Copy VMDK from Recovery VM to Target VM Working Directory Write-Host "Copying $recoveryHD from $Source to $Target $NewVMDK ..." -ForeGroundColor Cyan $recoveryVM = Get-VM $Source $recoveryWORK = $recoveryVM | Get-HardDisk | Where {$_.Name -eq "$recoveryHD"} | Copy-HardDisk -DestinationPath $NewVMDK #Attach copied VMDK to Target VM Write-Host "Attaching $NewVMDK to $Target ..." -ForeGroundColor Cyan $targetVM | New-HardDisk -DiskPath $NewVMDK | Out-Null Write-Host "Done!" -ForeGroundColor Cyan
An up-to-date version of this PowerCLI script can be found on GitHub: copy_recoveryVMDK.ps1
The script determines the current working directory of the target VM by determining where the VM’s “Hard disk 1” is stored ($targetDIR) using the Get-HardDisk cmdlet. The name and location for the new vmdk ($NewVMDK) is determined using the $targetDIR and the $dateTime in the format MMddyyhhmmss.
The vmdk associated with the $recoveryHD from the $Source is then copied to $NewVMDK using Copy-HardDisk.
Once the copy is complete, $NewVMDK is attached to the $Target with New-HardDisk. The disk is now available in the guest but it is “Offline”.
To bring the disk online the Windows powershell code below will set the disk to read/write and then bring the disk “Online”
# Set Offline Disk to Read/Write Get-Disk | where {$_.OperationalStatus -eq "Offline"} | Set-Disk -IsReadOnly $false # Bring Offline Disk Online Get-Disk | where {$_.OperationalStatus -eq "Offline"} | Set-Disk -IsOffline $false
The volume is now available to the guest OS.
Hope you find this useful. Thoughts, comments, and questions are always welcome.
Have a great day!