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 removedAnonymous
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 R2Anonymous
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 removedAnonymous
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, BenAnonymous
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? -JamesAnonymous
December 14, 2011
The comment has been removedAnonymous
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-b330f1763d05Anonymous
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 youAnonymous
August 29, 2013
Does anyone know if configurations exported under Windows 2008 R2 and be imported in Windows 2012 R2 ? Thank youAnonymous
January 10, 2014
The comment has been removedAnonymous
January 10, 2014
The comment has been removedAnonymous
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 removedAnonymous
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!