Hyper-V: Scripting Fixed VHD Creation

Hyper-V: Scripting Fixed VHD Creation

  • Comments 3

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

Leave a Comment
  • Please add 2 and 6 and type the answer here:
  • Post
  • Why is fixed disk creation so slow? It has no partitions. It isn't formatted. Shouldn't it just create a big empty file?

    Regards,

  • Jason -

    When we create a new fixed virtual hard disk we zero out the contents so that there is no chance for accidental data disclosure from the parent environment.

    Cheers,

    Ben

  • 1. Is there a code in C# which does the same task?

    2. Also, if there is an existing VM which has a vhd already present, what would happen if I run this method on that VM?

    3. Is there a way, I can delete the existing vhd and create a new vhd in its place?

Page 1 of 1 (3 items)