Welcome to MSDN Blogs Sign in | Join | Help

Hyper-V: Scripting Dynamic VHD Creation

Today I would like to show you some basic scripts for creating a new dynamically expanding virtual hard disk.  The tricky thing about doing this is that the WMI interfaces for creating virtual hard disks expect the size of the new virtual hard disk to be specified as a UINT64.  This requires some special handling - but can be done in both VBScript and PowerShell.

VBScript:

Option Explicit
 
'Setup constant to use for getting the right value for the new VHD size
const Size1G = &H40000000
 
Dim HyperVServer
Dim VHDName
Dim VHDSize
Dim WMIService
Dim Msvm_ImageManagementService
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 dynamic virtual hard disk on:")
 
'Get name for VHD
VHDName = InputBox("Specify the name of the new dynamic virtual hard disk:")
 
'Get size for VHD
VHDSize = InputBox("Specify the size of the new dynamic virtual hard disk (in GB):") * Size1G
 
'Get an instance of the WMI Service in the virtualization namespace.
Set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
 
'Get the Msvm_ImageManagementService object
Set Msvm_ImageManagementService = WMIService.ExecQuery("SELECT * FROM Msvm_ImageManagementService").ItemIndex(0)
 
'Setup the input parameter list
Set InParam = Msvm_ImageManagementService.Methods_("CreateDynamicVirtualHardDisk").InParameters.SpawnInstance_()
InParam.Path = VHDName 
InParam.MaxInternalSize = VHDSize
 
'Execute the method and store the results in OutParam
Set OutParam = Msvm_ImageManagementService.ExecMethod_("CreateDynamicVirtualHardDisk", InParam) 
 
'Check to see if the job completed synchronously
if (OutParam.ReturnValue = 0) then
   Wscript.Echo "The virtual hard disk has been created."
elseif (OutParam.ReturnValue <> 4096) then
   Wscript.Echo "The virtual hard disk has not been created."
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 "Creating VHD. " & Job.PercentComplete & "% complete"
      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 "The virtual hard disk has not been created."
      Wscript.Echo "ErrorCode:" & Job.ErrorCode
      Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
   else
      Wscript.Echo "The virtual hard disk has been created."
   end If
end if
 

PowerShell:

# Setup constant to use for getting the right value for the new VHD size
[UInt64]$Size1G = 0x40000000
 
# Prompt for the Hyper-V Server to use
$HyperVServer = Read-Host "Specify the Hyper-V Server to use (enter '.' for the local computer)"
 
# Get name for VHD
$VHDName = Read-Host "Specify the name of the new dynamic virtual hard disk"
 
# Get size for VHD
[UInt64]$VHDSize = Read-Host "Specify the size of the new dynamic virtual hard disk (in GB)" 
 
# Get the Msvm_ImageManagementService object
$ImageManagementService = gwmi Msvm_ImageManagementService -namespace "root\virtualization" -computername $HyperVServer
 
# Compact the VHD
$result = $ImageManagementService.CreateDynamicVirtualHardDisk($VHDName, $VHDSize * $Size1G)
 
#Return success if the return value is "0"
if ($Result.ReturnValue -eq 0)
   {write-host "The virtual hard disk has been created."} 
 
#If the return value is not "0" or "4096" then the operation failed
ElseIf ($Result.ReturnValue -ne 4096)
   {write-host "The virtual hard disk has not been created.  Error value:" $Result.ReturnValue}
 
  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 "Creating. "$job.PercentComplete "% complete"
       start-sleep 1
 
       #Refresh the job object
       $job=[WMI]$Result.job}
 
     #A jobstate of "7" means success
    if ($job.JobState -eq 7)
       {write-host "The virtual hard disk has been created."}
      Else
       {write-host "The virtual hard disk has not been created."
        write-host "ErrorCode:" $job.ErrorCode
        write-host "ErrorDescription" $job.ErrorDescription}
   }

Cheers,
Ben

Published Thursday, September 25, 2008 10:52 PM by Virtual PC Guy

Comments

Sunday, September 28, 2008 4:19 PM by christian

# re: Hyper-V: Scripting Dynamic VHD Creation

how about copying vhd to physical drive?

Tuesday, October 07, 2008 2:58 AM by Virtual PC Guy

# re: Hyper-V: Scripting Dynamic VHD Creation

We do not provide a way to do that "in-box".  You could mount a virtual hard disk in the parent partition and then use a third party disk imaging tool to copy the data from the virtual hard disk to a physical hard disk.

Cheers,

Ben

New Comments to this post are disabled
 
Page view tracker