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

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

  • Comments 18


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

Leave a Comment
  • Please add 4 and 7 and type the answer here:
  • Post
  • Exactly what the doctor ordered! Thx for publishing this script!

    To export or import a complete VM in an accelerated manner with minimized disk I/O, combine this script with the VHDCopEE tool from www.VMUtil.com ! VHDCopEE will read and write only the parts of the VHD NTFS is using and will optionally zero fill the rest. So if you are copying a 200 GB fixed size VHD with 50 GB occupied, only 50 GB of data crosses the wire. The 150GB worth of zeros are optionally written by the file system on the destination.

  • Hi Ben,

    When i try to run the script, providing the following input

    server: localhost

    vm : <vmname> in my case, wsus

    path: c:\backup

    the script fails with the message:The virtual machine has been exported.

    I am running this locally on 2k8 R2

  • Found the source of my issue. User issue, it helps to shutdown the vm first.

  • When I copy the code into notepad, everything is in one line only.

    Not a big deal, I'll sort it, but is it possible that you save the code in some downloadable form (like zip) or whatever.

    Otherwise, a great article, like many here. I'm a regular lurker and keep up the good work.

  • I was just looking a making this into a powershell script when i discovered the PowerShell  Management Library for Hyper-V (http://pshyperv.codeplex.com/) which includes export-vm which by default is config only.

  • Ben, I have just compared the output from the powershell library to the output your script produces, and I think there are some problems with your script.

    Firstly, your script still copies the bin and vsv files for a vm which is in the saved state. Secondly, in the config.xml file at the root fo the directory, <VmStateCopied type="bool">true</VmStateCopied> which from my understanding should be false.

  • DS -

    This is an unfortunate side effect of the tool that I use to make the code look pretty.  An easy solution is to paste the code into wordpad first.

    Kieran Jacobsen -

    I intentionally included the bin and vsv files.  I wanted everything exported except for the VHD files.

    Cheers,

    Ben

  • Thanks for publishing the script! Gave me a leg up. Any chance you've encountered the issue of being unable to import a config-only export of a VM with multiple levels of diff disks?

  • Absolutely awesome script.   Server 2008 had the option to export config only.  I did an in-place upgrade to R2, and the hyper-v role did not upgrade so I had to reinstall the role.  Then I found out there was no config only import option in the GUI.  Do I seriously need Microsoft to move my VHD's around for me?  

    THANKS!

  • Roy B -

    I'm having what sounds like a similar problem. I can import a VM that uses multiple levels of disks under a certain condition.

    Given the following diff disk chain: a.vhd <-- b.vhd <-- (c.vhd, d.vhd), where c.vhd and d.vhd are children of b.vhd, a.vhd is the "root", and VM C uses c.vhd and VM D uses d.vhd, I can import and start VM C - but doing so prohibits hyperv from importing VM D.  Actually, the import of VM D sort-of completes, except that it gives a warning that b.vhd is already in use - and it refuses to populate the IDE connection with d.vhd.

    I can manually (either via the UI or powershell) re-attach d.vhd to VM D and start it up just fine.

    Any thoughts as to why the import fails?

    -James

  • I saved the scripts from the link above as configexp.vbs (for the export) and configimp.vbs (for the import).

    Here's what I'm doing:

    (1) create VHD d:\testcase1\a.vhd, 2GB

    (2) create VHD d:\testcase1\b.vhd, diff disk with parent d:\testcase1\a.vhd

    (3) create VHD d:\testcase1\c.vhd, diff disk with parent d:\testcase1\b.vhd

    (4) create VHD d:\testcase1\d.vhd, diff disk with parent d:\testcase1\c.vhd

    (5) create VHD d:\testcase1\e.vhd, diff disk with parent d:\testcase1\c.vhd

    (6) create VM D, 512MB memory, 1 cpu, no networks, use d.vhd as the disk

    (7) create VM E, 512MB memory, 1 cpu, no networks, use e.vhd as the disk

    (8) start VM D, wait for it to start completely

    (9) start VM E, wait for it to start completely

    (10) observe that they both start up OK

    (11) stop VM D, wait for it to stop completely

    (12) stop VM E, wait for it to stop completely

    (13) cscript configexp.vbs, enter the name of the server, enter D as the VM, enter d:\D-export as the target path, click OK, the export completes

    (14) cscript configexp.vbs, enter the name of the server, enter E as the VM, enter d:\E-export as the target path, click OK, the export completes

    (15) delete VM D from hyperv -- observe that the VHDs are still in place

    (16) delete VM E from hyperv -- observe that the VHDs are still in place

    (17) cscript configimp.vbs, enter the name of the server, enter  d:\D-export\D as the import path, click OK, import completes

    (18) start VM D, wait for it to start completely

    (19) cscript configimp.vbs, enter the name of the server, enter d:\E-export\E as the import path, click OK, import fails

    (20) Observe the following error message on the console:

    Get the import settings object.

    Importing virtual machine. 10% complete

    The virtual machine has not been imported.

    ErrorCode:0

    ErrorDescription:Import completed with warnings. Please check the Admin events in the Hyper-V-VMMS event log for more information.

    (21) Observe that the error in the event log complains about c.vhd being already in use.

    (22) In the hyperv UI, examine VM D, observe that it is using d.vhd (which is expected)

    I believe this to be a bug in hyperv.  I performed *every* step here using the hyperv UI except for the execution of the vbs scripts.

  • For anyone following the import problem, there's a thread on the support forum:

    social.technet.microsoft.com/.../886189d8-7c0a-4baf-b20b-b330f1763d05

  • Does anyone know how to fix the problem with access Hyper-V manager. I recieve an error stating the domain admin doesn't have the rights to open the mmc or virftmgmr.msc doesn't exits. I think the problem came from installing hyper-v before joining the 2012 server to the doamin.

    Thank  you

  • Does anyone know if configurations exported under Windows 2008 R2 and be imported in Windows 2012 R2 ?

    Thank you

  • Thanks so much for posting this. We've been having an issue with getting replication working on 100+ VMs (3 TB each) due to the large amount of time it takes to move them (and subsequently the changes not having enough space to be stored on the original server).

    So the alternative route is to import/export the VM and move the vhds separately and then start the replication (and hope it can replicate before it runs out of space).

    The issue is on one of the VMs I'm running into the following error -

    C:\export.vbs(28, 1) SWbemObjectSet: Invalid class

    While I've confirmed the same usage works on at least 4 other VMs. Could it be because the new VM is on a Windows 2012 R2 server?

Page 1 of 2 (18 items) 12