Scripting VM Creation with Hyper-V
People have been bugging me for this for a while - so here we go.
Here are the VBScripts / PowerShell scripts to create a basic virtual machine:
VBScript:
Option Explicit
Dim HyperVServer
Dim VMName
Dim WMIService
Dim VSManagementService
Dim VSGlobalSettingData
Dim Result
Dim Job
Dim InParam
Dim OutParam
'Prompt for the Hyper-V Server to use
HyperVServer = InputBox("Specify the Hyper-V Server to create the virtual machine on:")
'Prompt for the new VM name
VMName = InputBox("Specify the name for the new virtual machine:")
'Get an instance of the WMI Service in the virtualization namespace.
Set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
'Get the VirtualSystemManagementService object
Set VSManagementService = WMIService.ExecQuery("SELECT * FROM Msvm_VirtualSystemManagementService").ItemIndex(0)
' Initialize a new global settings for the VM
Set VSGlobalSettingData = WMIService.Get("Msvm_VirtualSystemGlobalSettingData").SpawnInstance_()
'Set the VM name
VSGlobalSettingData.ElementName = VMName
'Setup the input parameter list
Set InParam = VSManagementService.Methods_("DefineVirtualSystem").InParameters.SpawnInstance_()
InParam.SystemSettingData = VSGlobalSettingData.GetText_(1)
'Execute the method and store the results in OutParam
Set OutParam = VSManagementService.ExecMethod_("DefineVirtualSystem", InParam)
'Check to see if the job completed synchronously
if (OutParam.ReturnValue = 0) then
Wscript.Echo "Virtual machine created."
elseif (OutParam.ReturnValue <> 4096) then
Wscript.Echo "Failed to create virtual machine"
else
'Get the job object
set Job = WMIService.Get(OutParam.Job)
'Wait for the job to complete (3 == starting, 4 == running)
while (Job.JobState = 3) or (Job.JobState = 4)
Wscript.Echo Job.PercentComplete
WScript.Sleep(1000)
'Refresh the job object
set Job = WMIService.Get(OutParam.Job)
Wend
'Provide details if the job fails (7 == complete)
if (Job.JobState <> 7) then
Wscript.Echo "Failed to create virtual machine"
Wscript.Echo "ErrorCode:" & Job.ErrorCode
Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
else
Wscript.Echo "Virtual machine created."
end If
end if
PowerShell:
# Prompt for the Hyper-V Server to use
$HyperVServer = Read-Host "Specify the Hyper-V Server to create the virtual machine on"
# Get name for new VM
$VMName = Read-Host "Specify the name for the new virtual machine"
# Create new MSVM_VirtualSystemGlobalSettingData object
$wmiClassString = "\\" + $HyperVServer + "\root\virtualization:Msvm_VirtualSystemGlobalSettingData"
$wmiClass = [WMIClass]$wmiClassString
$newVSGlobalSettingData = $wmiClass.CreateInstance()
# wait for the new object to be populated
while ($newVSGlobalSettingData.psbase.Properties -eq $null) {}
# Set the VM name
$newVSGlobalSettingData.psbase.Properties.Item("ElementName").value = $VMName
# Get the VirtualSystemManagementService object
$VSManagementService = gwmi MSVM_VirtualSystemManagementService -namespace "root\virtualization" -computername $HyperVServer
# Create the VM
$result = $VSManagementService.DefineVirtualSystem($newVSGlobalSettingData.psbase.GetText(1))
#Return success if the return value is "0"
if ($Result.ReturnValue -eq 0)
{write-host "Virtual machine created."}
#If the return value is not "0" or "4096" then the operation failed
ElseIf ($Result.ReturnValue -ne 4096)
{write-host "Failed to create virtual machine"}
Else
{#Get the job object
$job=[WMI]$Result.job
#Provide updates if the jobstate is "3" (starting) or "4" (running)
while ($job.JobState -eq 3 -or $job.JobState -eq 4)
{write-host $job.PercentComplete
start-sleep 1
#Refresh the job object
$job=[WMI]$Result.job}
#A jobstate of "7" means success
if ($job.JobState -eq 7)
{write-host "Virtual machine created."}
Else
{write-host "Failed to create virtual machine"
write-host "ErrorCode:" $job.ErrorCode
write-host "ErrorDescription" $job.ErrorDescription}
}
The basic concept here is that you need to create a new instance of Msvm_VirtualSystemGlobalSettingData and then pass it to the DefineVirtualSystem method on the MSVM_VirtualSystemManagementService object.
This will create a new blank virtual machine with no virtual hard disks, network adapters, etc... (I will dig into creating virtual machines with all these bits later).
Note that both of these scripts allow you to specify a remote Hyper-V server to create the virtual machine on.
Cheers,
Ben