Hyper-V: Scripting Dynamic VHD Creation

Hyper-V: Scripting Dynamic VHD Creation

  • Comments 2

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

Leave a Comment
  • Please add 4 and 1 and type the answer here:
  • Post
  • how about copying vhd to physical drive?

  • 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

Page 1 of 1 (2 items)