Cloning Hyper-V VMs with PowerShell

Unlike when using Windows Admin Center to manage your Hyper-V VMs, Hyper-V Manager, nor the built-in cmdlets, offer any native VM cloning function. But with a bit of creative scripting, it's certainly doable. Here is a script that clones a virtual machine in Hyper-V:

Update 3/8/2025: I added a fix to prevent trying to import any snapshots. Thank you, Yvan Pinard, for the tip!

# Script to clone a VM in Hyper-V
# Author: Johan Arwidmark
# Twitter: @jarwidmark
# LinkedIn: https://www.linkedin.com/in/jarwidmark

$SourceVMName = "PC0001"
$CloneVMName = "PC0001-CLONE"
$ExportFolder = "E:\Export"
$CloneFolder = "F:\VMs\$CloneVMName"

If (Test-Path $CloneFolder){
    Write-Warning "Clone folder: $CloneFolder already exists. Aborting script..."
    Break
}

# Export the Source VM
Export-VM $SourceVMName -Path $ExportFolder

# Import the Exported VM, full copy, and generating a new ID
$CloneVMConfigFile = (Get-ChildItem "$ExportFolder\$($ReferenceVM.Name)\Virtual Machines" -Filter *.vmcx -Recurse | Select -First 1).Fullname

$CloneVMConfig = @{
    Path = $CloneVMConfigFile;
    SnapshotFilePath = Join-Path $CloneFolder "Snapshots";
    VhdDestinationPath = Join-Path $CloneFolder "Virtual Hard Disks";
    VirtualMachinePath = $CloneFolder;
}

$Result = Import-VM -Copy -GenerateNewID @CloneVMConfig 

# Rename the imported VM (will be imported with original name)
$Result | Rename-VM -NewName $CloneVMName

# Remove the exported VM
$SourceVMExportPath = "$ExportFolder\$SourceVMName"
If (Test-Path $SourceVMExportPath) { Remove-Item -Path $SourceVMExportPath -Recurse -Force }
About the author

Johan Arwidmark

2 1 vote
Article Rating
Subscribe
Notify of
guest
3 Comments
Newest
Oldest Most Voted
Garry Schindler
Garry Schindler
1 year ago

Interesting. For me, the $ReferenceVM.Name was not a valid variable to use. I had to flip that same line to this instead: $CloneVMConfigFile = (Get-ChildItem "$ExportFolder\$SourceVMName)\Virtual Machines" -Filter *.vmcx -Recurse | Select -First 1).Fullname

Last edited 1 year ago by Garry Schindler
Yvan Pinard
Yvan Pinard
1 year ago

Thank you Johan,
Small correction :
$CloneVMConfigFile = (Get-ChildItem "$ExportFolder\$($ReferenceVM.Name)\Virtual Machines" -Filter *.vmcx -Recurse | Select -First 1).Fullname

>> There is also a .vmcx file in the "Snapshots" folder, which could cause an error during the Import-VM command. I added "Virtual Machines" to the path to avoid this issue.


>