Skip to content

Instantly share code, notes, and snippets.

@aaronNGi
Created October 14, 2022 10:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aaronNGi/3447525bac2cbad50669a6716d1073f2 to your computer and use it in GitHub Desktop.
Save aaronNGi/3447525bac2cbad50669a6716d1073f2 to your computer and use it in GitHub Desktop.
Script for easy cloning of MS Hyper-V VMs
# Creates clones of HyperV virtual machines
# Author: Aaron Gießelmann
# Date: 22-10-14
function die {
$_.Exception
exitwait 1
}
function exitwait {
param ( $exitcode )
Read-Host "Press Enter to exit"
exit $exitcode
}
# Array of VMs
try { $vms = Get-VM }
catch { die }
# Enumerate VMs so the user can select a VM by number
# For the users side we use one-based indexing
For ($i = 0; $i -lt $vms.Length; $i++ ) {
Write-Output "$($i+1) $($vms[$i].VMName)"
}
Write-Output ""
$num = Read-Host "VM number to clone [1]?"
if ($num -eq "") {
$num = 1
}
# Convert back to zero-based indexing
$num -= 1
# Make sure the selection is within the arrays length
If ($num -lt 0 -or $num -ge $vms.Length) {
Write-Output "Invalid input"
exitwait 1
}
$vm = $vms[$num]
# VM name
$name = $vm.Name
$newname = Read-Host "Name of the cloned VM [$name clone]?"
if ($newname -eq "") {
$newname = "$name clone"
}
# VM path
$defaultpath = "C:\HyperV\$newname"
$outpath = Read-Host "Location of the cloned VM [$defaultpath]?"
if ($outpath -eq "") {
$outpath = $defaultpath
}
try { $outpath | Test-Path }
catch { die }
# The Import-VM command needs a *.vmcx file which "should" be located in the Virtual Machines folder, let's find that dir
$vmdir = Get-ChildItem -Recurse -Directory -Path $vm.Path | where-object -property Name -Clike "Virtual Machines"
$vmfile = "$($vmdir.FullName)\$($vm.Id.ToString()).vmcx"
# Print summary
Write-Output "" `
"Summary:" `
"VM to clone: $vm" `
"Name: $newname" `
"Destination directory: $outpath" `
""
# After showing the summary, we let the user decide whether or not to continue
switch (Read-Host "Continue [y/N]?") {
"n" { exitwait }
"" { exitwait }
"y" { }
default { exitwait }
}
# Clone the selected VM
try {
$newvm = Import-VM -Copy -GenerateNewId `
-Path "$vmfile" `
-VhdDestinationPath "${outpath}\Virtual Hard Disks" `
-VirtualMachinePath "$outpath" `
-SmartPagingFilePath "$outpath"
} catch { die }
# When importing a VM, it will have the same name as the original, let's rename it
try { Rename-VM -VM $newvm -NewName "$newname" }
catch { die }
exitwait
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment