If you use Server 2012 Hyper-V but don’t have the luxury of System Center Virtual Machine Manager to do provisioning of new virtual machines for you then I offer here a PowerShell script, with GUI, that will do it for you from a master VHD/VHDX. I’ll also show you how to integrate it into explorer so you can just right click on a VHD/VHDX file and clone it from there.
I use Hyper-V at home and have SysPrep’d VHDs of all the Operating Systems I typically use but let’s not get into the debate, started by one Mark Russinovich, as to whether we actually need to SysPrep anymore – I’m old school so I do it out of habit more than anything.
So what we need to do to use an existing VHD to create a new VM is:
- Copy the VHD/VHDX to a new file or create a new differencing disk from it (aka a linked clone)
- Create a new VM with the new VHD/VHDX file as its disk
- Connect the VM to a network (optional)
- Start the VM (optional)
We start this process by right clicking the VHD that we want to copy in explorer:
and selecting the “Create VM” option which is a registry key I’ve created, which we’ll cover later, that runs the PowerShell script with the VHD/VHDX file as one of the arguments.
This then gives the user interface constructed on the fly by PowerShell:
All we have to do at this point if we are happy with the defaults is to enter the new virtual machine name and either click the “Create” button or hit Alt C or enter. Note that the VHD/VHDX destination folder is pre-populated with my personal default so I don’t have to type in or use the folder browser – this is done via the registry value we’ll see later and we can set other defaults in there too if we wish. The name of the new VHD/VHDX file will be the machine name that you have entered above or with a “- <number>” suffix if you create more than one VM at a time. If the destination VHD/VHDX file already exists then an error will be shown unless the “-force” option is specified which will cause the VHD/VHDX to be overwritten so use it wisely.
Depending on your storage, the file copy for a non-linked clone may take a while but you’ll find a PowerShell window behind the GUI with some rudiments of a progress indicator in there. You will also get a message box upon completion unless you specify the -quiet switch.
Also, if you run as an administrator but with UAC enabled (what I like to call the “sensible” option when running as an administrator (which I avoid as much as I can anyway)), the script will detect this and run itself again, but elevated, so you should expect to see a UAC elevation prompt. Without it elevated, it will probably fail due to lack of permission.
I’ve tested it just on Server 2012R2 English with PowerShell 4.0 and it certainly works reliably for me but I thought I’d share it lest it helps anyone else save time when creating new VMs from VHD/VHDX files. It won’t work on Server 2008/2008 R2 as they don’t have PowerShell support for Hyper-V (out of the box anyway).
It’s quick to use to as it has been designed to be used via the keyboard so you can tab through the fields and hit “enter” to start the creation process at any point. There are also keyboard accelerators – activated by hitting the “Alt” key. Hitting the escape key will quit immediately.
Note that it won’t work with AVHD/AVHDX files or snapshots as the disk cloning is done completely outside of Hyper-V – it just uses the Hyper-V PowerShell cmdlets to check if a VM of the name you entered exists already and if not to create a new VM, set the generation and number of processors and start it if requested.
The script can be downloaded here and is used entirely at your own risk. Any error messages will be displayed in a message box.
To integrate it into explorer, create a new key with the name you want in your right click explorer menu (mine is “Create VM” as shown above) in “HKEY_CLASSES_ROOT\Windows.VhdFile\shell”. In the key you create, create another key called “command” and set the default value in this “command” key to be something like this (obviously substituting your preferred default destination folder for my G: drive folder example or just leave out the -Folder option if you are happy to always enter or browse to a folder):
powershell.exe -command “& ‘c:\scripts\Clone VHD.ps1’ -Verbose -ShowUI -Folder \”G:\Hyper-V\Hyper-V Hard Drives\” -SourceVHD \”%1\”
So it looks like this in regedit – make sure you get all the single and double quote marks correct otherwise spaces in any argument will stop it working:
A .reg file can be downloaded here – just change the path in it to wherever you save the PowerShell script and the argument to the -Folder switch to your default folder for Hyper-V hard drives to be stored.
The script can also be run without the GUI in a PowerShell session, e.g.:
& ‘c:\scripts\Clone VHD.ps1’ -SourceVHD “c:\folder\source.vhdx” -Name “My new VM” -Switch “External virtual switch” -Start -LinkedClone -Folder “d:\hyper-v\hyper-v hard drives”
where you need to change paths and virtual switches to match your system. Full help is available for it via Get-Help.
If the script won’t run due to the PowerShell execution policy then run “Set-ExecutionPolicy -ExecutionPolicy RemoteSigned” as an administrative user but please understand the implications of this before doing so. If it still won’t set the execution policy because of group policy then as an administrator change the “ExecutionPolicy” value in “HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell” to “RemoteSigned” although this is only a temporary workaround as it will eventually reapply the original value due to group policy refresh.