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