How to Export and Import Hyper-V Virtual Machines on Windows Server 2022
Exporting and importing Hyper-V virtual machines on Windows Server 2022 is the primary method for moving VMs between non-clustered hosts, creating portable backups, duplicating VMs for testing, and migrating workloads to new hardware. Understanding the export structure and the three import modes available is essential for performing these operations correctly without data loss or configuration corruption.
What Export-VM Does
The Export-VM cmdlet creates a complete, self-contained copy of a virtual machine. The export captures everything needed to recreate the VM on any Hyper-V host: the VM configuration file (VMCX format on Server 2022), all attached virtual hard disk files (VHDX or VHD), any checkpoints (snapshots) and their associated differencing disks, and checkpoint runtime state files if the VM was in a saved or paused state.
Importantly, Export-VM does not remove the original VM. It creates a new copy at the destination path. The original VM continues running (if it was running) during the export. Hyper-V uses VSS (Volume Shadow Copy Service) and VM-level tracking to ensure the export is consistent.
Export a running VM:
Export-VM -Name "WebServer01" -Path "E:Exports"
This creates the directory structure E:ExportsWebServer01. The export is a copy, not a live snapshot — changes made to the VM after export starts are not included in the export (the state is captured at the moment export begins for differencing disks).
Understanding the VM Export Directory Structure
After running Export-VM, the destination folder contains a specific structure that Hyper-V uses during import. Understanding this structure helps you verify exports, manually move files, and troubleshoot import failures.
E:ExportsWebServer01
├── Virtual Machines
│ └── {GUID}.vmcx ← VM configuration file
│ └── {GUID}.vmrs ← Runtime state (if VM was saved/paused)
├── Virtual Hard Disks
│ └── WebServer01_OS.vhdx ← OS disk
│ └── WebServer01_Data.vhdx ← Data disk (if any)
├── Snapshots
│ └── {Checkpoint-GUID}.vmcx ← Checkpoint config
│ └── {Checkpoint-GUID}.vmrs ← Checkpoint runtime state
│ └── {Checkpoint-GUID} ← Checkpoint differencing disks
The VMCX file is the XML-based VM configuration format introduced in Windows Server 2016. It replaces the older XML (.xml) format used in Server 2012 R2 and earlier. You cannot edit VMCX files manually — they are binary encoded.
Verify the export completed successfully and all expected files are present:
Get-ChildItem -Path "E:ExportsWebServer01" -Recurse | Select-Object FullName, Length
To find the VMCX file for use with Import-VM:
Get-ChildItem -Path "E:ExportsWebServer01Virtual Machines" -Filter "*.vmcx"
Exporting Multiple VMs
Export all VMs on a host to a backup location:
$exportPath = "E:Exports"
Get-VM | ForEach-Object {
Write-Host "Exporting $($_.Name)..."
Export-VM -Name $_.Name -Path $exportPath
Write-Host "Done: $($_.Name)"
}
Export only VMs in the off or saved state (to ensure consistent full disk exports without tracking overhead):
Get-VM | Where-Object { $_.State -in @('Off', 'Saved') } | ForEach-Object {
Export-VM -Name $_.Name -Path "E:Exports$(Get-Date -Format 'yyyy-MM-dd')"
}
Export a VM on a remote host to a path on that remote host:
Export-VM -Name "DBServer01" -Path "D:Exports" -ComputerName "HV-HOST-02"
The Three Import Modes Explained
When importing a VM with Import-VM, you must choose from three distinct modes. Choosing the wrong mode is the most common source of confusion and errors during VM import.
Register in place — registers the VM using the files exactly where they currently are. No files are moved or copied. The VM ID is preserved (same GUID as the original). Use this when you have already manually moved the export files to where you want them permanently. If a VM with the same ID already exists on the host, this will fail.
Restore — copies the VM files from the import source to a specified destination path, preserving the original VM ID. Use this when you want to place the files in a specific location and the original VM ID does not exist on the destination host. If the original VM still exists on the source host with the same ID, and both hosts are in the same environment, this can cause ID conflicts with SCVMM or backup software.
Copy — copies the VM files to a specified destination path and generates a new unique VM ID. Use this when you want to create a duplicate of a VM (cloning) or when the original VM still exists and you need to avoid ID conflicts. This is the safest choice for most migration scenarios.
Importing VMs with Import-VM
To import using Register in place (files are already in their final location, no copy performed):
Import-VM -Path "E:VMsWebServer01Virtual Machines{8D4D0E12-B56A-4B3E-9A2C-1234567890AB}.vmcx"
To import using Restore (copy files to a specific location, keep original VM ID):
Import-VM -Path "E:ExportsWebServer01Virtual Machines{8D4D0E12-B56A-4B3E-9A2C-1234567890AB}.vmcx" `
-Copy `
-VhdDestinationPath "D:VMsWebServer01" `
-VirtualMachinePath "D:VMsWebServer01"
Wait — that uses Copy mode. To use Restore mode explicitly:
Import-VM -Path "E:ExportsWebServer01Virtual Machines{8D4D0E12-B56A-4B3E-9A2C-1234567890AB}.vmcx" `
-VhdDestinationPath "D:VMsWebServer01" `
-VirtualMachinePath "D:VMsWebServer01"
To import using Copy mode (new VM ID, safe for cloning or when original still exists):
Import-VM -Path "E:ExportsWebServer01Virtual Machines{8D4D0E12-B56A-4B3E-9A2C-1234567890AB}.vmcx" `
-Copy `
-GenerateNewId `
-VhdDestinationPath "D:VMsWebServer01-Copy" `
-VirtualMachinePath "D:VMsWebServer01-Copy"
If you do not know the exact GUID path, use PowerShell to find it automatically:
$vmcxPath = Get-ChildItem -Path "E:ExportsWebServer01Virtual Machines" -Filter "*.vmcx" | Select-Object -First 1 -ExpandProperty FullName
Import-VM -Path $vmcxPath -Copy -GenerateNewId -VhdDestinationPath "D:VMsWebServer01-Copy" -VirtualMachinePath "D:VMsWebServer01-Copy"
Moving VMs Between Hosts Without a Cluster
When hosts are not clustered, Export-VM and Import-VM is the standard offline migration method. The process involves exporting, transferring files over the network, and importing on the destination host.
Step 1 — Shut down the VM (recommended for a fully consistent state):
Stop-VM -Name "AppServer01"
Step 2 — Export to a network share accessible from both hosts:
Export-VM -Name "AppServer01" -Path "\FileServerVMTransfer"
Step 3 — On the destination host, import the VM:
$vmcxPath = Get-ChildItem -Path "\FileServerVMTransferAppServer01Virtual Machines" -Filter "*.vmcx" | Select-Object -First 1 -ExpandProperty FullName
Import-VM -Path $vmcxPath -Copy -GenerateNewId `
-VhdDestinationPath "D:VMsAppServer01" `
-VirtualMachinePath "D:VMsAppServer01"
If the hosts are on the same network and you want minimal downtime, consider using storage migration after export rather than copy-then-import. However, for cross-network migrations or hardware replacements, the export/import approach is more reliable.
Exporting VMs with Checkpoints
When a VM has checkpoints (snapshots), the export includes all checkpoint data. This means the export size will be larger than just the VHDX files since all differencing disks in the checkpoint chain are included.
View checkpoints for a VM before exporting:
Get-VMCheckpoint -VMName "WebServer01"
If you want a clean export without checkpoints (smaller file size, simpler import), first merge all checkpoints by deleting them. This merges the checkpoint differencing disks back into the base VHDX:
Get-VMCheckpoint -VMName "WebServer01" | Remove-VMCheckpoint
Wait for the merge to complete before exporting. The VM disk size may temporarily increase during the merge process as blocks are written back to the parent disk. Check if the merge is done:
Get-VM -Name "WebServer01" | Select-Object Name, Status
The status returns to “Operating normally” once the merge is complete.
Importing from Older Hyper-V Versions and Format Conversion
Windows Server 2022 can import VMs exported from older Hyper-V hosts (Server 2012 R2, 2016, 2019). However, there are compatibility considerations.
VMs from Server 2012 R2 use the old XML configuration format (.xml files) instead of VMCX. To import an older XML-format VM on Server 2022:
Import-VM -Path "E:OldExportsWebServer01Virtual Machines{GUID}.xml" `
-Copy -GenerateNewId `
-VhdDestinationPath "D:VMsWebServer01" `
-VirtualMachinePath "D:VMsWebServer01"
After importing an older generation VM, the configuration version will be upgraded to the Server 2022 format when you update the VM configuration version:
Get-VM -Name "WebServer01" | Select-Object Name, Version
Update to the latest configuration version (allows use of new Server 2022 features but makes the VM incompatible with older hosts):
Update-VMVersion -VMName "WebServer01" -Force
Check what configuration version a VM uses:
Get-VM | Select-Object Name, Version | Sort-Object Version
On Server 2022, the default new VM configuration version is 10.0. VMs created on Server 2012 R2 may be at version 5.0. Updating the version is irreversible — downgrade is not possible without re-exporting from the older host.
Export-VM vs Storage Migration: When to Use Each
Both Export-VM and Move-VMStorage move VM disk files, but they serve different purposes and have different behavior.
Use Export-VM when: you want a full point-in-time backup copy, you are archiving a VM before major changes, you are moving to a non-networked destination, you want to create multiple identical copies (clone), or the source and destination hosts are not connected by a reliable high-speed network.
Use storage migration (Move-VMStorage) when: the VM must remain running during the move, the source and destination are accessible over the network, you are rebalancing storage within the same Hyper-V environment, and you do not need a backup copy.
# Storage migration (VM stays running, no export file created)
Move-VMStorage -VMName "WebServer01" -DestinationStoragePath "E:VMsWebServer01"
# Export creates a backup copy (VM keeps running, separate copy is created)
Export-VM -Name "WebServer01" -Path "E:Exports"
A practical workflow for large-scale migrations between non-clustered hosts using PowerShell automation:
$sourceVMs = Get-VM -ComputerName "HV-SOURCE"
$exportPath = "\SharedTransferVMExports"
$destHost = "HV-DEST"
$destVMPath = "D:VMs"
foreach ($vm in $sourceVMs) {
Write-Host "Exporting $($vm.Name)..."
Stop-VM -Name $vm.Name -ComputerName "HV-SOURCE"
Export-VM -Name $vm.Name -Path $exportPath -ComputerName "HV-SOURCE"
$vmcx = Get-ChildItem -Path "$exportPath$($vm.Name)Virtual Machines" -Filter "*.vmcx" | Select-Object -First 1
Write-Host "Importing $($vm.Name) on $destHost..."
Invoke-Command -ComputerName $destHost -ScriptBlock {
param($vmcxPath, $destPath)
Import-VM -Path $vmcxPath -Copy -GenerateNewId `
-VhdDestinationPath "$destPath$([System.IO.Path]::GetFileName([System.IO.Path]::GetDirectoryName([System.IO.Path]::GetDirectoryName($vmcxPath))))" `
-VirtualMachinePath "$destPath$([System.IO.Path]::GetFileName([System.IO.Path]::GetDirectoryName([System.IO.Path]::GetDirectoryName($vmcxPath))))"
} -ArgumentList $vmcx.FullName, $destVMPath
Write-Host "Completed: $($vm.Name)"
}
The export and import process is reliable and well-suited to planned migrations. With the PowerShell techniques in this guide, you can automate large-scale VM migrations without manual intervention for each virtual machine.