How to Export and Import Hyper-V Virtual Machines on Windows Server 2025
Exporting and importing Hyper-V virtual machines is one of the most versatile techniques in a Windows Server administrator’s toolkit. Whether you need to migrate a VM between hosts that lack shared storage, create a deployable VM template for rapid provisioning, clone an existing system for testing, or simply archive a VM before decommissioning it, the export-import workflow provides a clean, self-contained solution. Windows Server 2025 retains the three import types introduced in earlier generations — Register, Restore, and Copy — while benefiting from faster VHDX copying on NVMe storage and enhanced SMB 3.1.1 throughput for network-based transfers. This tutorial covers the full export-import lifecycle, from capturing a running VM through to deploying copies across multiple hosts.
Prerequisites
- Windows Server 2025 with the Hyper-V role installed on source and destination hosts
- PowerShell 5.1 or later running as Administrator
- Sufficient disk space at the export destination to hold a complete copy of the VM’s VHDXs and configuration
- For cross-host migrations: network connectivity between the source and destination, or a shared intermediate storage location (SMB share, USB drive, portable SSD)
- Hyper-V Integration Services installed in the guest OS for checkpoint-consistent exports
Step 1: Exporting a VM with Export-VM
Export-VM creates a self-contained copy of the virtual machine at a specified path. The export includes the VM configuration XML, all attached VHDXs, and any saved state files. If the VM has checkpoints, those are exported too. The VM can remain running during the export (Hyper-V takes an internal checkpoint and exports a consistent copy), though exporting a stopped VM is faster and avoids the checkpoint overhead.
# Export a single VM to a local path
# The cmdlet creates a subfolder named after the VM automatically
Export-VM -Name 'WebServer01' -Path 'D:Exports'
# Export to a network share (useful for cross-host migrations)
Export-VM -Name 'WebServer01' -Path '\FILESERVER01VMExports'
# Export from a remote Hyper-V host
Export-VM -Name 'WebServer01' -ComputerName 'HVHOST02' -Path 'D:Exports'
# Export multiple VMs in parallel using background jobs
$vmsToExport = 'WebServer01', 'AppServer01', 'DBServer01'
$jobs = $vmsToExport | ForEach-Object {
$vmName = $_
Start-Job -ScriptBlock {
Export-VM -Name $using:vmName -Path 'D:Exports'
}
}
$jobs | Wait-Job | Receive-Job
$jobs | Remove-Job
# Verify the export structure
Get-ChildItem -Path 'D:ExportsWebServer01' -Recurse | Select-Object FullName, Length
The export folder for each VM contains three subdirectories: Virtual Machines (configuration XML and GUID-named files), Virtual Hard Disks (all attached VHDXs), and Snapshots (checkpoint data, if any).
Step 2: Understanding the Three Import Types
When importing a VM, Hyper-V offers three distinct import modes. Choosing the wrong one can result in duplicate VM IDs causing conflicts on clustered hosts, or unexpected file movements. Understanding the differences is critical before running Import-VM.
- Register in Place: Registers the VM configuration XML directly from the export folder. No files are copied. The VM’s original GUID is preserved. Use this when you want to register a VM from a permanent storage location without moving any files.
- Restore: Copies the VM files to the default Hyper-V paths (or specified paths) and preserves the original VM GUID. Use this to restore a backup or move a VM to new storage. The original VM must not exist on the host (duplicate GUIDs cause conflicts).
- Copy (New Unique ID): Copies the VM files and assigns a new VM GUID. Use this to clone a VM — you can import the same export multiple times on the same host, each with a unique identity.
# Find the VM configuration file in the export — required for Import-VM
$exportPath = 'D:ExportsWebServer01'
$vmcxFile = Get-ChildItem -Path $exportPath -Filter '*.vmcx' -Recurse | Select-Object -First 1
Write-Output "Config file: $($vmcxFile.FullName)"
# Import Type 1: Register in place (no file copy, preserves original GUID)
Import-VM -Path $vmcxFile.FullName -Register
# Import Type 2: Restore (copies files, preserves original GUID)
Import-VM -Path $vmcxFile.FullName `
-VhdDestinationPath 'D:VHDs' `
-VirtualMachinePath 'D:VMs' `
-Copy:$false
# Import Type 3: Copy with new unique ID (cloning — generates a new VM GUID)
Import-VM -Path $vmcxFile.FullName `
-VhdDestinationPath 'D:VHDs' `
-VirtualMachinePath 'D:VMs' `
-Copy `
-GenerateNewId
# Verify the imported VM
Get-VM | Where-Object { $_.Name -like 'WebServer01*' }
Step 3: Migrating Between Hosts Without Shared Storage
When shared storage (SAN, SMB SOFS) is not available, export-import is the standard technique for moving VMs between standalone Hyper-V hosts. The workflow is: shut down the VM on the source host, export it to an intermediate location (or directly to the destination via a network share), then import it on the destination host.
# Step 1: Gracefully shut down the VM on the source host
Stop-VM -Name 'AppServer01'
# Step 2: Export directly to the destination host's storage via SMB
Export-VM -Name 'AppServer01' -Path '\HVHOST02D$VMImports'
# Step 3: On the destination host, discover the config file and import
$configFile = Get-ChildItem -Path 'D:VMImportsAppServer01' -Filter '*.vmcx' -Recurse |
Select-Object -First 1
Import-VM -Path $configFile.FullName `
-VhdDestinationPath 'D:VHDs' `
-VirtualMachinePath 'D:VMs' `
-Copy `
-GenerateNewId
# Step 4: Start the imported VM on the destination host and verify
Start-VM -Name 'AppServer01'
Get-VM -Name 'AppServer01' | Select-Object Name, State, MemoryAssigned, ProcessorCount
# Step 5: Once the VM is confirmed running on HVHOST02, clean up the import staging area
Remove-Item -Path 'D:VMImportsAppServer01' -Recurse -Force
Step 4: Creating and Deploying VM Templates
Exporting a fully configured, sysprepped VM creates a reusable template that can be deployed repeatedly. This is the on-premises equivalent of a VM image in a cloud environment. Export once, import many times using the Copy import type to generate unique VM IDs for each new instance.
# Assumptions: 'WS2025-Template' is a VM that has been sysprepped and shut down
# Export it to a templates share
Export-VM -Name 'WS2025-Template' -Path '\FILESERVER01VMTemplates'
# Mark the export folder as read-only to protect the template
$templatePath = '\FILESERVER01VMTemplatesWS2025-Template'
Get-ChildItem -Path $templatePath -Recurse |
Set-ItemProperty -Name IsReadOnly -Value $true
# Deploy function: import a copy with a new name
function Deploy-VMFromTemplate {
param(
[string]$NewVMName,
[string]$TemplatePath,
[string]$DestinationHost,
[string]$VhdPath,
[string]$VMPath,
[int64]$MemoryBytes = 4GB,
[int]$vCPUs = 2
)
$configFile = Get-ChildItem -Path $TemplatePath -Filter '*.vmcx' -Recurse | Select-Object -First 1
# Import as a copy with a new unique ID
$vm = Import-VM -ComputerName $DestinationHost `
-Path $configFile.FullName `
-VhdDestinationPath $VhdPath `
-VirtualMachinePath $VMPath `
-Copy `
-GenerateNewId
# Rename and configure the new VM
Rename-VM -VM $vm -NewName $NewVMName
Set-VMMemory -VMName $NewVMName -ComputerName $DestinationHost -StartupBytes $MemoryBytes
Set-VMProcessor -VMName $NewVMName -ComputerName $DestinationHost -Count $vCPUs
Write-Output "Deployed: $NewVMName on $DestinationHost"
}
# Deploy three VMs from the same template
Deploy-VMFromTemplate -NewVMName 'WebFarm01' -TemplatePath $templatePath `
-DestinationHost 'HVHOST01' -VhdPath 'D:VHDs' -VMPath 'D:VMs'
Deploy-VMFromTemplate -NewVMName 'WebFarm02' -TemplatePath $templatePath `
-DestinationHost 'HVHOST02' -VhdPath 'D:VHDs' -VMPath 'D:VMs'
Deploy-VMFromTemplate -NewVMName 'WebFarm03' -TemplatePath $templatePath `
-DestinationHost 'HVHOST02' -VhdPath 'D:VHDs' -VMPath 'D:VMs'
Step 5: Compressing Exports for Archival
VM exports can consume tens or hundreds of gigabytes. For long-term archival, compressing the export folder significantly reduces storage requirements, especially for dynamic VHDX files that have not been fully written. Use Compress-Archive for smaller VMs, or a dedicated tool like 7-Zip for large exports where the built-in cmdlet’s 2 GB file limit would be a problem.
# Compress a VM export to a ZIP archive (PowerShell built-in, suitable for VMs up to ~2 GB uncompressed)
Compress-Archive -Path 'D:ExportsWebServer01' `
-DestinationPath 'D:ArchivesWebServer01_2026-05-17.zip' `
-CompressionLevel Optimal
# For larger VMs, use 7-Zip from the command line (must be installed)
& 'C:Program Files7-Zip7z.exe' a -t7z -mx=5 `
'D:ArchivesLargeVM_2026-05-17.7z' `
'D:ExportsLargeVM'
# Extract and import from the ZIP archive when needed
Expand-Archive -Path 'D:ArchivesWebServer01_2026-05-17.zip' `
-DestinationPath 'D:Restored'
$configFile = Get-ChildItem -Path 'D:RestoredWebServer01' -Filter '*.vmcx' -Recurse |
Select-Object -First 1
Import-VM -Path $configFile.FullName `
-VhdDestinationPath 'D:VHDs' `
-VirtualMachinePath 'D:VMs' `
-Copy `
-GenerateNewId
Step 6: Inspecting Exports and Handling Import Errors
Before importing an export that was created on a host with different hardware or configuration, inspect the configuration file and check for compatibility warnings. Import failures are most commonly caused by missing virtual switch names, device paths that no longer exist, or VM configuration version mismatches.
# Compare VM configuration version of export vs destination host
$configFile = 'D:ExportsWebServer01Virtual Machines.vmcx'
# Read the configuration XML to inspect hardware configuration
[xml]$vmConfig = Get-Content $configFile
$vmConfig.configuration.properties | Select-Object *
# Check what virtual switches the VM expects
Get-VMNetworkAdapter -Path $configFile
# List virtual switches available on the destination host
Get-VMSwitch -ComputerName 'HVHOST02'
# If the switch name differs, specify a replacement at import time
Import-VM -Path $configFile `
-VhdDestinationPath 'D:VHDs' `
-VirtualMachinePath 'D:VMs' `
-Copy `
-GenerateNewId
# After import, fix the network adapter connection if the switch name changed
Get-VMNetworkAdapter -VMName 'WebServer01' | Connect-VMNetworkAdapter -SwitchName 'External-vSwitch'
# Upgrade VM configuration version if the destination host is a newer Hyper-V version
Update-VMVersion -VMName 'WebServer01' -Force
Conclusion
The export and import workflow in Hyper-V on Windows Server 2025 is a powerful and flexible mechanism that spans use cases from simple host-to-host migration through to systematic template-based VM deployment. Understanding the three import types — Register, Restore, and Copy — is essential for avoiding VM identity conflicts and choosing the right behaviour for each scenario. Combining Export-VM with PowerShell pipelines and a shared staging location makes it straightforward to migrate entire workloads between hosts, archive VMs before major changes, and maintain a library of deployable templates. For environments that require frequent provisioning, pairing this approach with a naming convention, a deployment script, and an automated post-import configuration step (such as a domain-join script triggered by Sysprep) creates a practical lightweight provisioning system without requiring System Center Virtual Machine Manager.