Hi guys, after some painful research and testing, I've finally finished a test release of a script that will clone a hot VM's OS disk whilst ignoring the other disks. It seems that defining a VM configuration and discarding the disks, still copies the disks, even in the latest PowerCLI version, so I took a different approach.
Many thanks to Lucd for his examples on other posts and some support feedback from Alan regarding the usage of the CopyVirtualDisk_Task call - which was once experimental.
The script is to be run within our live environment where we have DB boxes assorted into certain clusters and very strict naming conventions, these servers have -DB at the end of their inventory names and the datastores match these names with _OS appended to the end of them, hence the filters within the script that allows you to filter by host, VM, cluster and even datacentre.
Thus far it only throws one error as it tries to connect twice to the same VC, otherwise, no errors if everything is fine.
Note that to use the VDM stuff you need to be connected to the host, hence the many nested loops and strange logic.
Any and all input appreciated. Cheers
##################################################
#Script will clone VM OS disks into root datastore
##################################################
Clear-Host
$VCIP = "X.X.X.X" #IP OF CENTRAL VC
$VCUID = "VCUID" #USERNAME FOR LOGIN TO VC
$VCKEY = "VCPASS" #PASSWORD FOR ABOVE VC USERNAME
$HUID = "HUID" #USERNAME FOR LOGIN TO HOST
$HKEY = "HPASS" #PASSWORD FOR ABOVE HOST USERNAME
Connect-VIServer -Server $VCIP -User $VCUID -Password $VCKEY
$DC = Get-Datacenter -Name "LIVEPRIMARY"
$CLUSTERS = Get-Cluster | Sort Name
foreach($C in $CLUSTERS)
{
if ($ClusterName -like "*DBCLUS*")
{
$ClusterName = $C.Name
Write-Host "Working on cluster:"
Write-Host $ClusterName
Connect-VIServer -Server $VCIP -User $VCIP -Password $VCKEY
$HOSTS = $C | Get-VMHost | Sort Name
Disconnect-VIServer -Server $VCIP -Force:$true -Confirm:$false
foreach($H in $HOSTS)
{
If ($H -like "*")
{
Write-Host "Connected to host:"
Write-Host $H
Connect-VIServer -Server $H.Name -User $HUID -Password $HKEY
$VMS = Get-VM | Sort Name
foreach ($VM in $VMS)
{
$srcDC = (Get-View (($VM | Get-Datacenter))).moref
$VMname = $VM.Name
If ($VMname -like "*-DB*")
{
$SI = Get-View ServiceInstance
$VDM = Get-View $SI.Content.VirtualDiskManager
$snapName = "TEMPCLONESNAP"
$targetFileName = $VMname + "_CLONE.vmdk"
$DSname = $VMname.Split("-")[0] + "_OS"
$DS = Get-Datastore -Name $DSname
Write-Host "Working on VM:"
Write-Host $VMname
$VM | New-Snapshot -Memory:$false -Quiesce:$false -Confirm:$false -Name $snapName
$snapDisks = (($VM | Get-Snapshot -Name $snapName) | Get-HardDisk)
foreach ($HD in $snapDisks)
{
if ($HD.Name -eq "Hard disk 1")
{
$srcDS = $HD.Filename
$destDS = "[$DSname] $targetFileName"
$destSpec = New-Object VMware.Vim.VirtualDiskSpec
$destSpec.adapterType = "lsiLogic"
$destSpec.diskType = "thin"
$force = $false
$taskMoRef = $VDM.DeleteVirtualDisk_Task($destDS, $srcDC)
$taskMoRef = $VDM.CopyVirtualDisk_Task($srcDS, $srcDC, $destDS, $srcDC, $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")
{
$info = Get-Task | Where {$_.id -like "*-" + $task.info.key}
$task = Get-View $taskMoRef
Write-Host "Clone task" $task.info.state ":" $info.PercentComplete "% complete."
Sleep 15
}
Get-VM $VM | Get-Snapshot -Name $snapName| Remove-Snapshot -Confirm:$false
break
}
}
}
}
}
Disconnect-VIServer -Server $H.Name -Force:$true -Confirm:$false
}
}
}
Write-Host "SCRIPT COMPLETE"