Hyper-V: Scripting Fixed VHD Creation

This script is practically identically to the one for creating a dynamically expanding virtual hard disk.  The big thing to be aware of is that creation of a fixed size virtual hard disk takes a lot longer - so you need to make sure you handle the concrete job object and use it to know when the virtual hard disk has finished being created.

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 fixed virtual hard disk on:")
  
 'Get name for VHD
 VHDName = InputBox("Specify the name of the new fixed virtual hard disk:")
  
 'Get size for VHD
 VHDSize = InputBox("Specify the size of the new fixed 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_("CreateFixedVirtualHardDisk").InParameters.SpawnInstance_()
 InParam.Path = VHDName 
 InParam.MaxInternalSize = VHDSize
  
 'Execute the method and store the results in OutParam
 Set OutParam = Msvm_ImageManagementService.ExecMethod_("CreateFixedVirtualHardDisk", 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 fixed virtual hard disk"
  
 # Get size for VHD
 [UInt64]$VHDSize = Read-Host "Specify the size of the new fixed virtual hard disk (in GB)" 
  
 # Get the Msvm_ImageManagementService object
 $ImageManagementService = gwmi Msvm_ImageManagementService -namespace "root\virtualization" -computername $HyperVServer
  
 # Create the VHD
 $result = $ImageManagementService.CreateFixedVirtualHardDisk($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