Using virtual machines to test things has become almost a second nature exercise for some folks. Here’s a method to deploy a duplicate of a Hyper-V virtual machine in less than ten seconds with PowerShell.
What? Ten seconds? Yep, and it’s actually a little quicker than that, but I like to leave a little time padding.
The method I am using to do this is called thin provisioning. In the past, thin provisioning has gotten a bad rap. In my humble opinion, most of the bad reputation stems from the poor or uninformed use of the method by less experienced administrators. You still have to manage and monitor your environment; you can’t just call thin provisioning the magic bullet for your storage woes, because it’s not.
Thin provisioning is the act of using virtualization technology to give the appearance of having more physical resources than are actually available. For example, lets say that a developer needs a VM with 500 GB of hard drive space. In thin provisioning, the Hyper-V VHDX or VMWare VMDK file would start out as a couple of megabytes, with the potential to grow to the full 500 GB. Basically, the actual physical storage is given to the VM dynamically, as needed, transparent to the operation of the guest OS.
It’s possible to over-provision most things in modern HyperVisors,in the case of storage, this method makes it really easy to over-provision a disk or LUN, thereby quickly running it out of space, and killing your VMs. That’s why you need to have a capacity management monitoring process in place, especially if you are using thin provisioning.
Done properly, thin provisioning can easily help you to increase storage utilization, and simplify capacity management.
In the example below, I’ve used PowerShell to deploy a new Windows 7 virtual machine calld Win7Clone based on a “template” vm called WinBaseTest.
#
# Set from/to/where
#
$SourceMachine="WinBaseTest" # VM to be duplicated
$TargetMachine="Win7Clone" # VM to be created
$VMDefaultPath="C:\admin\ISO\vmchildren" # Root path for child VMs
#
# Get some values from the source machine
#
$BMAC=Get-VM -Name $SourceMachine # Get data for the source VM
$StartMemory=$BMAC.MemoryStartup # How much memory for startup?
$VMID=$BMAC.VMID # VMID is used to get the vhdx path
$SVHD=get-vhd -vmid $VMID # using Get-VHD with VMID
$SVHD=$SVHD.path # but we only need the path
#
# create target machine
#
new-vm -name $TargetMachine
Set-vm -Name $TargetMachine -Notes "Clone of $SourceMachine"
Set-vm -Name $TargetMachine -DynamicMemory -MemoryStartupBytes $StartMemory
new-vhd -path $VMDefaultPath\$TargetMachine\$TargetMachine.vhdx -ParentPath $SVHD
Add-VMHardDiskDrive -vmname $TargetMachine -ControllerType IDE -ControllerNumber 0 -path $VMDefaultPath\$TargetMachine\$TargetMachine.vhdx
Connect-VMNetworkAdapter -VMName $TargetMachine -SwitchName MyVMSwitch
I’ve commented the majority of the code inline, except for the bottom section, where the magic happens. Still, you should be able to get the gist of the process:
- Create a new VM called %TargetMachine
- Set a note on the vm, denoting it as a clone. I do this to help keep track of things.I’m also setting the memory mode of the new vm as dynamic, with a startup memory matching the source vm.
- New VHDx file is created in a subdirectory of the default new VM path, with the source vm disk file as the parent.
- The new VHDx is added to IDE 0 on the new VM.
- Finally, the new VM is connected to a virtual switch.
This is just a really short example of deploying a basic, thin-provisioned virtual machine with PowerShell and Hyper-V, which can be easily expanded on. I myself have a version of this that deploys whole lab environments, on private networks, with duplicates of actual production servers. It works really well, and allows me to test concepts in a private, fenced environment.
Questions? Comments? Improvements?