Windows Server 2012 – Hyper-V over SMB – Quick Provisioning a VM on an SMB File Share

One of the preferred methods for creating VMs in a shared environment is to have one or more base VHDs that you use as a template for new VMs. While having a base VHD is a constant, there are a few different methods to choose when you implement your provisioning process for new VMs. This post looks at the provisioning options available when using SMB file shares as shared storage for your VMs.

 

Option 1 – Differential VHD

You can easily provision new VMs using differential VHD, which creates a second VHD file that contains the difference between your new VM and the base. Creating a differential VHD is practically instantaneous. However, the base needs to remain unchanged during the lifetime of the differential VHDs. If you need to apply a change to the base, you essentially need to create a new version of it and you need to keep the previous one around for as long as there are differentials based on it. You could end up with several generations of base VHDs. This might be a great choice if you don’t keep your VMs around for a long time.

Here’s how you would do it:

New-VHD -Path \FSVMSHAREVM7.VHDX -ParentPath \FSVMSHAREBASE.VHDX
New-VM VM7 -Path \FSVMSHAREVM7 -VHDPath \FSVMSHAREVM7.VHDX -Memory 1GB
Start-VM VM7

Option 2 – Copy the base VHD

Another approach is to simply create a copy of the base VHD and use that copy as the VHD for your new VM. This will give you a completely separate VHD for every new VM, independent of the base VHD. However, this option will typically use more disk space and take longer to complete, since most base VHD files are a few gigabytes in size. The delay in the provisioning of a VM, while acceptable in some scenarios, might be a nuisance for your users, especially if you are using a self-service portal for provisioning. If you use this approach, though, you can change the base VHD at any time, without having to worry about dependencies by previously created VMs. This could be a great choice if your base changes frequently and your VMs will live for a long time. This is also a good choice if your system can leverage the new ODX (offloaded data transfers) capability, which will greatly accelerate the copy process.

Here’s how you would do it:

Copy-Item \FSVMSHAREBASE.VHDX\FSVMSHAREVM8.VHDX
New-VM VM8 -Path \FSVMSHAREVM8 -VHDPath \FSVMSHAREVM8.VHDX -Memory 1GB
Start-VM VM8

Option 3 – A little bit of both

In Windows Server 2012, due to the ability to perform online VHDs merges and re-parent VHDs, there is a third way to do this. It essentially involves creating a snapshot before you start the VM, copying the base VHD while the VM is already running and then merging the snapshot with its own copy of the base. The end result gives you a quick provisioning process, where the VM starts almost immediately, but it become completely independent of the base VHD just a few minutes later. The down side of this solution is that the provisioning process gets a bit more complex, and you will have some extra work to do in the first few minutes of the VM lifecycle. Here are the details on how to do it…

Step 1 – Create the VM using the base

Start with a file share that contains the base VHD you want to use. Create a new VM using the base VHD. The base is a read-only file, so don’t start the VM just yet!

Dir \FSVMSHARE
New-VM VM9 -Path \FSVMSHAREVM9 -VHDPath \FSVMSHAREBASE.VHDX | FL Name, State
Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath

Step 2 – Snapshot and start

Create a temporary snapshot of the VHD file. Verify it succeeded. Now you can start the VM and hand it over to the end user, just a few seconds into the process.

Checkpoint-VM VM9
Dir \FSVMSHARE
Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath
Start-VM VM9

Step 3 – Copy the base

Now make a copy of the read-only base VHD into a unique instance for the VM. That might take a while, but that’s OK. The user is already happily using the VM. You can use whatever tool you want to copy the file. This could also leverage ODX (offloaded data transfers) if available on that system.

Copy-Item \FSVMSHAREBASE.VHDX\FSVMSHAREVM9.VHDX
Dir \FSVMSHARE

Step 4 – Re-parent to the copy

After the copy is done, you can “re-parent” your snapshot while your VM is running. This is new in this release. After this operation, the VM is no longer using the original base VHD.

Get-VMHardDiskDrive VM9 | Set-VHD -ParentPath \FSVMSHAREVM9.VHDX
Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath

Step 5 – Merge the snapshot

The last step is to remove the temporary snapshot, which will merge it into the VHD you created for this unique VM instance. Note that this operation is also done while the VM is running, which is also new in this release.

Remove-VMSnapshot VM9
Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath
Dir \FSVMSHARE
Get-VM VM9 | FL Name, State, Uptime

Reviewing the output of the entire set of commands

 

PS C:>
Dir \FSVMSHARE  
Directory: \FSVMSHARE
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 3/14/2012 7:53 PM 8996782080 BASE.VHDX

PS C:> New-VM VM9 -Path \FSVMSHAREVM9 -VHDPath \FSVMSHAREBASE.VHDX | FL Name, State
 
Name : VM9
State : Off
 
PS C:> Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath
 
Path : \FSVMSHAREBASE.VHDX
VhdType : Dynamic
ParentPath :

PS C:> Checkpoint-VM VM9
PS C:>
Dir \FSVMSHARE
    Directory: \FSVMSHARE
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/14/2012 7:54 PM VM9
-a--- 3/14/2012 7:55 PM 8996782080 BASE.VHDX
-a--- 3/14/2012 7:55 PM 4194304 BASE_2691830B-9046-4818-930E-D7D7C41A7028.avhdx

PS C:> Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath

Path : \FSVMSHAREBASE_2691830B-9046-4818-930E-D7D7C41A7028.avhdx
VhdType : Differencing
ParentPath : \FSVMSHAREBASE.VHDX
 
PS C:> Start-VM VM9
PS C:>
Copy-Item \FSVMSHAREBASE.VHDX \FSVMSHAREVM9.VHDX PS C:>
Dir \FSVMSHARE
    Directory: \FSVMSHARE
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/14/2012 7:54 PM VM9
-a--- 3/14/2012 7:55 PM 8996782080 BASE.VHDX
-a--- 3/14/2012 7:57 PM 205520896 BASE_2691830B-9046-4818-930E-D7D7C41A7028.avhdx
-a--- 3/14/2012 7:57 PM 8996782080 VM9.VHDX
 
PS C:>
Get-VMHardDiskDrive VM9 | Set-VHD -ParentPath \FSVMSHAREVM9.VHDX PS C:> Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath

Path : \FSVMSHAREBASE_2691830B-9046-4818-930E-D7D7C41A7028.avhdx
VhdType : Differencing
ParentPath : \FSVMSHAREVM9.VHDX
 
PS C:> Remove-VMSnapshot VM9
PS C:> Get-VMHardDiskDrive VM9 | Get-VHD | FL Path, VhdType, ParentPath
 
Path : \FSVMSHAREVM9.VHDX
VhdType : Dynamic
ParentPath :

PS C:>
Dir \FSVMSHARE  
Directory: \FSVMSHARE
 
Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 3/14/2012 7:54 PM VM9
-a--- 3/14/2012 7:55 PM 8996782080 BASE.VHDX
-a--- 3/14/2012 7:57 PM 8996782080 VM9.VHDX
 
PS C:> Get-VM VM9 | FL Name, State, Uptime
 
Name : VM9
State : Running
Uptime : 00:01:45
 
PS C:>

Conclusion

As you see, the VM was running since Step 2, seconds into the whole process. It took us a few minutes to copy the base and merge the snapshot, but the end user was happily using the VM after just a few seconds into the process.