Performing a “configuration only” export / import on Hyper-V

The next challenge I faced during my big rebuild of my Hyper-V server was what to do with my Windows Home Server virtual machine.  This is a single virtual machine that has a total of 6TB of storage attached to it – so backing it up to a remote location is out of the question.  Luckily none of the virtual hard disks for this virtual machine are stored on the system disk that was getting replaced.

This means that all I really want to do is perform a “configuration only” export and import of the virtual machine.  Specifically I want to export everything about the virtual machine – except for the virtual hard disks.  This is possible to do with Hyper-V – but not using the user interface that we ship.  Here are the scripts that I used for exporting and importing this virtual machine:

“Configuration only export”

 Option Explicit
  
 Dim HyperVServer
 Dim VMName
 Dim ExportPath
 Dim WMIService
 Dim Msvm_VirtualSystemManagementService
 Dim query
 Dim vm
 Dim InParam
 Dim exportSettingData
 Dim OutParam
 Dim Job
  
 'Prompt for the Hyper-V Server to use
 HyperVServer = InputBox("Specify the Hyper-V Server to export the virtual machine from:")
  
 'Get name for the virtual machine to export
 VMName = InputBox("Specify the name of the virtual machine to export:")
  
 'Get location for the exported virtual machine
 ExportPath = InputBox("Specify the location to export the virtual machine configuration to:")
  
 'Get an instance of the WMI Service in the virtualization namespace.
 Set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
  
 'Get the Msvm_VirtualSystemManagementService object
 Set Msvm_VirtualSystemManagementService = WMIService.ExecQuery("Select * from Msvm_VirtualSystemManagementService").ItemIndex(0)
  
 'Get the virtual machine object
 query = "select * from Msvm_ComputerSystem where ElementName = '" & VMName & "'"
 Set vm = WMIService.ExecQuery(query).ItemIndex(0)
  
 'Setup the input parameter list
 Set InParam = Msvm_VirtualSystemManagementService.Methods_("ExportVirtualSystemEx").InParameters.SpawnInstance_()
 InParam.ComputerSystem = vm.Path_.Path
  
 Set exportSettingData = (vm.Associators_("Msvm_SystemExportSettingData", "Msvm_VirtualSystemExportSettingData")).ItemIndex(0)  
  
 exportSettingData.CopyVmStorage = False    
 exportSettingData.CopyVmRuntimeInformation = true    
 exportSettingData.CreateVmExportSubdirectory = true    
 exportSettingData.CopySnapshotConfiguration = 0    
  
 InParam.ExportSettingData = exportSettingData.GetText_(1)
 InParam.ExportDirectory = ExportPath
  
 'Execute the method and store the results in OutParam
 Set OutParam = Msvm_VirtualSystemManagementService.ExecMethod_("ExportVirtualSystemEx", InParam) 
  
 'Check to see if the job completed synchronously
 if (OutParam.ReturnValue = 0) then
    Wscript.Echo "The virtual machine has been exported."
 elseif (OutParam.ReturnValue <> 4096) then
    Wscript.Echo "The virtual machine has not been exported."
 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 "Exporting virtual machine. " & 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 machine has not been exported."
       Wscript.Echo "ErrorCode:" & Job.ErrorCode
       Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
    else
       Wscript.Echo "The virtual machine has been exported."
    end If
 end if

 

”Configuration only import”

 Option Explicit
  
 Dim HyperVServer
 Dim ImportPath
 Dim WMIService
 Dim Msvm_VirtualSystemManagementService
 Dim InParam
 Dim importSettingData
 Dim OutParam
 Dim Job
  
 'Prompt for the Hyper-V Server to use
 HyperVServer = InputBox("Specify the Hyper-V Server to import the virtual machine to:")
  
 'Get location for the exported virtual machine
 ImportPath = InputBox("Specify the location to import the virtual machine configuration from:")
  
 'Get an instance of the WMI Service in the virtualization namespace.
 Set WMIService = GetObject("winmgmts:\\" & HyperVServer & "\root\virtualization")
  
 'Get the Msvm_VirtualSystemManagementService object
 Set Msvm_VirtualSystemManagementService = WMIService.ExecQuery("Select * from Msvm_VirtualSystemManagementService").ItemIndex(0)
  
 'Get importSettingData
 set InParam = Msvm_VirtualSystemManagementService.Methods_("GetVirtualSystemImportSettingData").InParameters.SpawnInstance_()
 InParam.ImportDirectory = ImportPath
  
 set OutParam = Msvm_VirtualSystemManagementService.ExecMethod_("GetVirtualSystemImportSettingData", InParam)
     
 'Check to see if the job completed synchronously
 if (OutParam.ReturnValue = 0) then
    Wscript.Echo "Got the import settings object."
 elseif (OutParam.ReturnValue <> 4096) Then
    Wscript.Echo "Failed to get the import settings object."
    WScript.quit
 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 "Importing virtual machine. " & 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 "Failed to get the import settings object."
       Wscript.Echo "ErrorCode:" & Job.ErrorCode
       Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
       WScript.quit
    Else
       Wscript.Echo "Got the import settings object."
    End If
 end If
  
 Set importSettingData = OutParam.ImportSettingData
 importSettingData.GenerateNewId = False
 importSettingData.CreateCopy = False
 importSettingData.SourceResourcePaths = importSettingData.CurrentResourcePaths
 importSettingData.TargetNetworkConnections = importSettingData.SourceNetworkConnections
 importSettingData.Put_
     
 'Setup the input parameter list
 Set InParam = Msvm_VirtualSystemManagementService.Methods_("ImportVirtualSystemEx").InParameters.SpawnInstance_()
 InParam.ImportDirectory = ImportPath
 InParam.ImportSettingData = importSettingData.GetText_(1)
  
 'Execute the method and store the results in OutParam
 Set OutParam = Msvm_VirtualSystemManagementService.ExecMethod_("ImportVirtualSystemEx", InParam) 
  
 'Check to see if the job completed synchronously
 if (OutParam.ReturnValue = 0) then
    Wscript.Echo "The virtual machine has been imported."
 elseif (OutParam.ReturnValue <> 4096) then
    Wscript.Echo "The virtual machine has not been imported."
 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 "Importing virtual machine. " & 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 machine has not been imported."
       Wscript.Echo "ErrorCode:" & Job.ErrorCode
       Wscript.Echo "ErrorDescription:" & Job.ErrorDescription
    Else
       Wscript.Echo "The virtual machine has been imported."
    End If
 end If

Some things to note about these scripts:

  • Sorry – they are VBScript only.  This is simply because I wrote them for myself and I have not had the time / motivation to do PowerShell versions
  • When importing the virtual machine I tell Hyper-V that the virtual hard disks will be in the same location as they were to start with (importSettingData.SourceResourcePaths = importSettingData.CurrentResourcePaths) if this is not the case you will need to change this code
  • Hyper-V is performing a “non-copying” import in this case – so where ever the export files are will become the new virtual machine data root.  So you need to be careful about where you place the export files before you import them.

Cheers,
Ben