I have a VM with two disks. the first disk contains the OS and is a standard virtual disk. The second disk is Independent - Persistent. I would like to hot Clone ONLY the OS disk and ignore the Independent disk. I have a Powershell script that will clone a vm, but I need to find out how to skip the Independent disk.
It looks like it's possible to copy a selected vmdk from a downed VM, but I need to be able to do a hot clone. Is this possible through Powershell?
Here's the loop code. Replace the ## DO IT comment line and everything up to the ## Clean up comment with the following
## DO IT -- NOTE that CopyVirtualDisk_Task is 'experimental' as of vSphere 4.0 GA
$taskMoRef = $vdiskMgr.CopyVirtualDisk_Task($sourceDS, $sourceDC, $destDS, $destDC, $destSpec, $force) $task = Get-View $taskMoRef
$info = get-task | where {$_.id -like "*-"+$task.info.key} while ($task.Info.State -eq "running" -or $task.Info.State -eq "queued") { sleep 10
$info = get-task | where {$_.id -like "*-"+$task.info.key} $task = Get-View $taskMoRef
Write-Host "Task" $task.info.state "," $info.percentcomplete "% complete."
} } }
Are the remaining disks very large? It would probably be easier to hot clone the entire VM and then simply delete the other files.
Another option might be to initiate a snapshot on that VM and then perform a copy of the disk that you need cloned.
Welcome to the Community..
You can use VMware Converter to Clone by selecting the disk which is required.
The independent disk is quite large (500GB). I had thought about going the snapshot and copy route. I will check into that option. Converter is another option, but I'd prefer to automate the process if possible.
I looked into this a bit last year and was unable to come up with a way to do it that didn't get more complicated than I wanted it to be:
I determined that the method used to clone a VM (CloneVM) takes a VirtualMachineCloneSpec as its argument. That has within it a VirtualMachineConfigSpec, whichI have typically used that to reconfigure networking, vCPUs or vRAM. It does look like the VirtualDeviceConfigSpec[] array could be used to drop a specific device during the clone operation, but I haven't done that before.
If I get some free time, I'll see if I can peel back the layers and get something working.
It is possible to hot-copy a single disk, but you don't get the VMX file, so it isn't necessarily as clean as you probably want it. You'd essentially have to create a new VM and attach the cloned disk if you want to use it.
I tossed some code together that may serve as a starting point for you. I'll try to get back to it, but I've run out of time this morning.
I'm making an assumption that you know the "name" of the disk you want to exclude ("Hard disk 2", for example). There are more elegant ways to figure out which disk you want to exclude, but I wanted to attack the reconfiguration option that seems to be the problem here.
I believe this should get you going, but consider it slightly above pseudocode at this point. I did use it to clone a 2-VMDK VM in my environment and it only cloned the first disk, but YMMV:
$sourceVMname = "MySourceVM"
$targetVMname = "MyCloneTest"
$targetLocation = Get-Folder -Name "DB-Provision" | % {Get-View $_.ID} $DiskToExclude = "Hard disk 2"
$vm = Get-VM $sourceVMname
$vmmor = $vm | Get-View
# Get device key for the hard disk
foreach($dev in $vmmor.Config.Hardware.Device){ if ($dev.DeviceInfo.Label -ne $DiskToExclude){ continue } else { #Define the clone specification
$vmclonespec = New-Object VMware.Vim.VirtualMachineCloneSpec #Get information about the hard disk device $vmclonespec.config = New-Object VMware.Vim.VirtualMachineConfigSpec
## Define what to change in the cloned VM's Configuration
$vmclonespec.config.deviceChange = @() $vmclonespec.config.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec $vmclonespec.config.deviceChange[0].device = New-Object VMware.Vim.VirtualDevice $vmclonespec.config.deviceChange[0].device.key = $dev.Key $vmclonespec.config.deviceChange[0].device.unitnumber = $dev.UnitNumber $vmclonespec.config.deviceChange[0].operation = "remove" $vmclonespec.location = New-Object VMware.Vim.VirtualMachineRelocateSpec
$vmclonespec.powerOn = $false
$vmclonespec.template = $false
$vmmor.CloneVM_Task($targetLocation.MoRef, $targetVMname, $vmclonespec ) } }
Doug
It was annoying me and my meeting got delayed a bit, so here it is. If we assume that you've only got one large disk that you want to exclude and you really don't care about/know the name, replace the line
if ($dev.DeviceInfo.Label -ne $DiskToExclude){
with
if ($dev.Backing.DiskMode -ne "independent_persistent"){
and the script will clone while excluding the first independent_persistent hard disk it comes across in the source VM.
Doug
Thanks for your reply DougBaer. Both variations of your script ran against the powered off VM. On the edit settings screen of the clone, the independent disk was not listed, but when I looked in the LUN, it had still copied into the new clone folder. So it looks like it was successfully removed from the configuration, but still physically copied. This is a great start though, and now I have a base to work with.
That's rather disappointing. Here is something I had worked on before. It is kind of rough and probably needs some tweaking/updating for vSphere 5. As I mentioned, it can copy the disks but doesn't get the VMX. So, you get the VM's data but not the complete VM. I don't know if this meets your needs or might help. It works on VMs that are powered on.
# # VM-copy-vmdk.ps1
# Copy the persistent disks representing a VM from one datastore/file to another
# The copy will be made to a thin-provisioned VMDK
# $vmname = 'TestVM'
$tempsnapname = 'TEMP SNAPSHOT FOR CLONE'
$destinationDatastoreName = 'VMFS09'
$destinationFilePath = 'MyTestVM-CLONETEST.vmdk'
$vm = Get-VM
$vmname $hostname = $vm.vmhost.name # Connect to the host -- this is needed -- the VDM only relevant per host (in vSphere 4, at least)
Connect-VIServer -Server $hostname -Username root -Password password $vdiskMgr = Get-View (Get-View ServiceInstance).Content.VirtualDiskManager $sourceDC = (get-view (($vm | Get-Datacenter))).moref #create a new shapshot w/ quiesced disk and no memory state
$vm | New-Snapshot -Memory:$false -Quiesce:$true -Confirm:$false -Name $tempsnapname $snapdisks = (($vm | get-snapshot -Name $tempsnapname) | Get-HardDisk)
foreach ($hd in $snapDisks) { if ($hd.Persistence -eq 'Persistent') { $sourceDS = $hd.Filename $destDS = "[$destinationDatastoreName] $destinationFilePath"
$destDC = $sourceDC
$destSpec = New-Object VMware.Vim.VirtualDiskSpec
$destSpec.adapterType = "lsiLogic"
$destSpec.diskType = "thin"
$force = $false ## DO IT -- NOTE that CopyVirtualDisk_Task is 'experimental' as of vSphere 4.0 GA
$taskMoRef = $vdiskMgr.CopyVirtualDisk_Task($sourceDS, $sourceDC, $destDS, $destDC, $destSpec, $force)
#NEED TO PUT LOOP IN HERE TO WATCH/WAIT UNTIL TASK IS COMPLETE
} } ## Clean up the snapshot
Get-VM $vm | Get-Snapshot -Name $tempsnapname| Remove-Snapshot -Confirm:$false
(I never put in the loop to watch for completion of the clone task, and it doesn't show up in the vCenter 'Recent Tasks' list... and that means the Remove-Snapshot will fail because it is locked)
Doug
Here's the loop code. Replace the ## DO IT comment line and everything up to the ## Clean up comment with the following
## DO IT -- NOTE that CopyVirtualDisk_Task is 'experimental' as of vSphere 4.0 GA
$taskMoRef = $vdiskMgr.CopyVirtualDisk_Task($sourceDS, $sourceDC, $destDS, $destDC, $destSpec, $force) $task = Get-View $taskMoRef
$info = get-task | where {$_.id -like "*-"+$task.info.key} while ($task.Info.State -eq "running" -or $task.Info.State -eq "queued") { sleep 10
$info = get-task | where {$_.id -like "*-"+$task.info.key} $task = Get-View $taskMoRef
Write-Host "Task" $task.info.state "," $info.percentcomplete "% complete."
} } }
Thanks Doug. With your script I am able to copy the non independent vmdk to a new LUN while the VM is powered on. Would be nifty if the other VM files came with it, but for what I need this will work well. The main thing was to get a copy of the OS disk only without having to power down. Thanks again.
