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
Comments
Anonymous
June 03, 2008
Looks like HV management only works when running under administrator creds (runas for PS). Is there anyway to set permissions for accounts that are admins, but not running under runas admin?Anonymous
June 03, 2008
This is too easy. Please show us a modification of this newly created VM like: adding two network adapters, one with static MAC, one with dynamic MAC attaching these to an internal LAN and one to a private LAN attaching two disks, one to SCSI, one to IDE This will show the real challenges with the hyper-v API. Please also provide a code sample in VB.Net or C#.Anonymous
June 04, 2008
Found fix for runas here: http://blogs.technet.com/jhoward/archive/2008/04/01/part-4-domain-joined-environment-hyper-v-remote-management-you-do-not-have-the-requested-permission-to-complete-this-task-contact-the-administrator-of-the-authorization-policy-for-the-computer-computername.aspxAnonymous
June 05, 2008
Joe - More details will be coming - but I need to start with the building blocks. jamesweb - Also covered here: http://blogs.msdn.com/virtual_pc_guy/archive/2008/05/28/scripting-vm-creation-with-hyper-v.aspx#comments Cheers, BenAnonymous
June 13, 2008
Joe You can find some examples here http://dungkhoang.spaces.live.com/ /DungAnonymous
February 21, 2013
Hi Ben, can you show us how to boot the newly created vm using iso.Anonymous
May 07, 2013
I have created them from a hodge podge of sites for datacenter 2012 running hyper-v 3.0 stephanco.blogspot.com/.../new-vm-powershell-commandlet-to-easily.html stephanco.blogspot.com/.../detailed-report-of-your-hyper-v-server.htmlAnonymous
July 02, 2013
Hi All, Could you please suggest how can I create a VHD using an ISO image and then using this created VHD I attach to a newly created VM ?Anonymous
July 02, 2013
And I would be grateful if the script in .VBSAnonymous
March 03, 2014
Hi, any idea how a hyper-v snapshot can be renamed in rootvirtualizationv2? The old calls don't work any more.