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

image


Published 07 June 08 02:38 by Taylorb
Filed under: , ,

Comments

# EXEDY said on June 9, 2008 5:59 PM:

I didn't follow all that... is it resetting the SID somewhere or is it assumed that hte image is already preped?

# Taylorb said on June 10, 2008 2:11 AM:

Exedy,

It's assumed that the VM's are syspreped or that you have newsid.exe set to auto run (that's how I do it :-))

-taylor

# james.legan@xerox.com said on June 12, 2008 8:01 AM:

Taylor,

With appropriate permissions across the board, is there any reason why the source server (that contains the VM to be cloned) and the destination server that will host the new one could be two different servers?

Thanks,

Jim

Anonymous comments are disabled

About Taylorb

I have been working on virtualization solutions at Microsoft for over 4 years, I started on the team shortly after Microsoft acquired Connectix in 2003. I worked on Virtual Server where I tested a verity of things but focused on networking, serial, and power management. I currently lead the Hyper-V End-to-End team, we are responsible for ensuring the end to end functionality of Hyper-V, this includes working with customers/partners/oem’s/etc… to ensure we are testing and shipping the best quality software possible. I have also worked on the Microsoft 1394 (firewire) team, ACPI (power management) team, and did a brief stent on the Microsoft Smart Watch team as a contractor.

Search

This Blog

Syndication

Page view tracker