Condividi tramite


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

Comments

  • Anonymous
    March 25, 2010
    The comment has been removed

  • Anonymous
    March 25, 2010
    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

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

  • Anonymous
    March 25, 2010
    The comment has been removed

  • Anonymous
    March 25, 2010
    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.

  • Anonymous
    March 25, 2010
    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.

  • Anonymous
    April 18, 2010
    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

  • Anonymous
    March 01, 2011
    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?

  • Anonymous
    March 03, 2011
    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!

  • Anonymous
    December 13, 2011
    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

  • Anonymous
    December 14, 2011
    The comment has been removed

  • Anonymous
    December 22, 2011
    For anyone following the import problem, there's a thread on the support forum: social.technet.microsoft.com/.../886189d8-7c0a-4baf-b20b-b330f1763d05

  • Anonymous
    January 21, 2013
    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

  • Anonymous
    August 29, 2013
    Does anyone know if configurations exported under Windows 2008 R2 and be imported in Windows 2012 R2 ? Thank you

  • Anonymous
    January 10, 2014
    The comment has been removed

  • Anonymous
    January 10, 2014
    The comment has been removed

  • Anonymous
    January 22, 2014
    Use the script below that works properly in Windows 2012 R2 $vmName = "vmName" $expDir = 'd:vmexports' + $vmName $ns = 'rootvirtualizationv2' #Get VM Object $vm = gwmi -namespace $ns MSVM_ComputerSystem -computer "."| ?{$_.ElementName -eq $vmName} #Get VMMS object $vmms = gwmi -n $ns Msvm_VirtualSystemManagementService #Get export setting object $exp = gwmi -n $ns Msvm_VirtualSystemExportSettingData #If you dont want to copy the VHDs and AVHDs $exp[0].CopyVmStorage = $false #If you dont want to copy the Saved state $exp[0].CopyVmRuntimeInformation = $false #Perform Export $out = $vmms.ExportSystemDefinition($vm.Path.Path, $expDir, $exp[0].GetText(1)) #Perform Job handling if necessary if ($out.ReturnValue -eq 4096) {       $task = [Wmi]$out.Job;       while($task.JobState -eq 3 -or $task.JobState -eq 4)       {              $task.Get();              sleep 1;       }       if ($task.JobState -ne 7)       {              "Error exporting VM " + $task.ErrorDescription;       }                   else       {              "Export completed successfully..."       }     } elseif ($out.ReturnValue -ne 0) {       "Export failed with error : " + $out.ReturnValue; } else {       "Export completed successfully..." }

  • Anonymous
    January 28, 2014
    Jairo, THANKS!  Worked great so far... How about a corresponding Import Script with that?

  • Anonymous
    January 15, 2015
    The comment has been removed

  • Anonymous
    June 01, 2015
    Ben, thanks for many of your excellent Hyper-V related articles and efforts in the past many years.  Do you have any "EXPORT-VM" PowerShell 4.0 examples/sample-codes for Windows 2012 r2? Thanks again!