Hyper-V WMI – Cloning Virtual Machines Using Import/Export
I have officially given up on the “Hyper-V WMI Using PowerShell Scripts” serious, not because of lack of interest but because or extreme interest implying that I would need to do Part 5, 6, 7, 99… Counting past 5 is hard so from now on I will just title the posts for what they are doing. Today’s post is going to be an end-to-end script to create 10 clones of a given VM.
Here’s a quick tour of the script…
This script takes 4 parameters:
MasterVM – this is the name of the VM that will be cloned
Path – this is the base path where the clones will reside
NewName – this is what the cloned VM’s will be named
HyperVHost – this is the name of the host that the script will execute against
The function ProcessWMIJob takes the return of a WMI method call and then processes the job waiting for the job to complete and throwing an exception if the job failed.
The main part of the script retrieves the Msvm_VirtualSystemManagmentService class and the MasterVM’s Msvm_ComputerSystem. It then loops 10 times, first changing the name of the VM and then exporting the VM and finally re-importing the VM. After it completes the 10 interactions it restores the name of original name of the MasterVM.
param ( [string]$MasterVM = $(Throw "MasterVM required"), [string]$Path = $(Throw "Path required"), [string]$NewName = "VMCopy", [string]$HyperVHost = "localhost" ) function ProcessWMIJob { param ( [System.Management.ManagementBaseObject]$Result ) if ($Result.ReturnValue -eq 4096) { $Job = [WMI]$Result.Job while ($Job.JobState -eq 4) { Write-Progress -Id 2 -ParentId 1 $Job.Caption -Status "Executing" -PercentComplete $Job.PercentComplete Start-Sleep 1 $Job.PSBase.Get() } if ($Job.JobState -ne 7) { Write-Error $Job.ErrorDescription Throw $Job.ErrorDescription } } elseif ($Result.ReturnValue -ne 0) { Throw $Result.ReturnValue } Write-Progress $Job.Caption -Status "Completed" -PercentComplete 100 -Id 2 -ParentId 1 } #Main Script Body $VMManagementService = Get-WmiObject -Namespace root\virtualization -Class Msvm_VirtualSystemManagementService -ComputerName $HyperVHost $SourceVm = Get-WmiObject -Namespace root\virtualization -Query "Select * From Msvm_ComputerSystem Where ElementName='$MasterVM'" -ComputerName $HyperVHost $a = 0 while ($a -lt 10) { write-progress -Id 1 "Cloning Vm's" -Status "Executing" -percentcomplete (($a / 10)*100) $tempVMName = "$NewName - $a" $VMSettingData = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$SourceVm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState" -ComputerName $HyperVHost $VMSettingData.ElementName = $tempVMName $Result = $VMManagementService.ModifyVirtualSystem($SourceVm, $VMSettingData.PSBase.GetText(1)) ProcessWMIJob $Result $Result = $VMManagementService.ExportVirtualSystem($SourceVm, $TRUE, "$Path") ProcessWMIJob $Result $Result = $VMManagementService.ImportVirtualSystem("$Path\$tempVMName", $TRUE) ProcessWMIJob $Result $a ++ } write-progress -Id 1 -Completed $TRUE -Activity "Cloning Vm's" $VMSettingData = Get-WmiObject -Namespace root\virtualization -Query "Associators of {$SourceVm} Where ResultClass=Msvm_VirtualSystemSettingData AssocClass=Msvm_SettingsDefineState" -ComputerName $HyperVHost $VMSettingData.ElementName = $MasterVM $Result = $VMManagementService.ModifyVirtualSystem($SourceVm, $VMSettingData.PSBase.GetText(1)) ProcessWMIJob $Result |
- Taylor Brown
- Hyper-V Test Team
Comments
Anonymous
November 03, 2008
Hi I am quite new to Powershell and tried to do a copy paste of your script (as I am a Programmer I did at least understand what it should do). But I can't start the script which I name clonevm.ps1. Do you have a Link to where I could go for as I don't have the whole time learning PowerShelll from ground up just for Hyper-V (maybe later) :-)Anonymous
February 14, 2009
@Mathew: Well, you need some basic Powershell knowledge in order to understand these scripts as well. There are, for instance, implications with running unsigned code (IIRC) in Powershell. That might be the issue you're seeing. Pop over to Microsofts Powershell User's Guide (http://technet.microsoft.com/en-us/library/cc196356.aspx) and go through the basics - it'll be well worth it.Anonymous
April 12, 2010
Me too, I tried and it doesn't work. anybody can help me ? thankAnonymous
October 10, 2013
I am running this script from remote cumputer and gettgin below error. Can you help me this. Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:Usersadministrator.DOMAINDesktopclone.ps1:41 char:37
- $VMManagementService = Get-WmiObject <<<< -Namespace rootvirtualization -Class Msvm_VirtualSystemManagementService -ComputerName $HyperVHost + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:Usersadministrator.DOMAINDesktopclone.ps1:42 char:26
- $SourceVm = Get-WmiObject <<<< -Namespace rootvirtualization -Query "Select * From Msvm_ComputerSystem Where Elemen tName='$MasterVM'" -ComputerName $HyperVHost + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:Usersadministrator.DOMAINDesktopclone.ps1:66 char:37
- $VMManagementService = Get-WmiObject <<<< -Namespace rootvirtualization -Class Msvm_VirtualSystemManagementService -ComputerName $HyperVHost + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED)) At C:Usersadministrator.DOMAINDesktopclone.ps1:67 char:26
- $SourceVm = Get-WmiObject <<<< -Namespace rootvirtualization -Query "Select * From Msvm_ComputerSystem Where Elemen tName='$MasterVM'" -ComputerName $HyperVHost + CategoryInfo : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand