The technology of differencing disks in Hyper-V was presented by Microsoft quite a long time ago (in Hyper-V version for Windows Server 2008 if I’m not mistaken). Differential disks are used to create snapshots (checkpoints) and are widely used by various VM backup systems. When creating a snapshot or performing a backup, the current VM state is saved to a VHD file, and all changes are written to another differencing disk.
Differencing Disks in Hyper-V
Another interesting opportunity of differencing disks is creating some basic OS image (VHD file) with all necessary settings and software. Then using this image you can quickly deploy multiple virtual machines that use the VHD of the base image and write all changes to their own virtual disks. Thus, significant savings in disk space are achieved. The example below shows that using differential disks for 4 VMs based on a single vhd image will require only 40 GB of disk space, and with the traditional deployment model for the same machines you need 150 GB. The difference is quite significant, especially for fast and expensive SSD drives.
A Hyper-V differencing disk is one of the supported virtual disk types. However, unlike common VHD, it is rigidly attached to another parent disk The differential disk is a child disk and does not contain the full version of the data on the VM disk, only the changes the VM made during its operation, i.e. this is the data that differentiates it from the parent one.
The parent (template) VHD image stays untouched, and all child virtual machines created on the base of it write the changes to their own differencing disks. The size of a differencing disk is rather small (its maximum size can not exceed the size of the parent disk).
Creating a Reference VHD Image
You can create a reference VHD file using the Hyper-V Manager GUI or PowerShell. PowerShell is much faster.
Tip. Hyper-V module for Windows PowerShell must be installed to use the following cmdlets:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-Management-PowerShell
Create a new VHDX file.
new-vhd -path f:\vms\vhd\WinSrv2016Base.vhdx -SizeBytes 50GB –Dynamic
Create a new VM based on it:
new-vm -Name TemplateVM –Path f:\vms\vhd\ -VHDPath f:\vms\vhd\WinSrv2016Base.vhdx | `
set-vmmemory -DynamicMemoryEnabled $true -MaximumBytes 2GB -MinimumBytes 512MB -StartupBytes 1GB
Mount the ISO file with the image of the desired OS:
add-vmdvddrive -VMName TemplateVM -Path d:\WindowsServer2016DC.ISO
After you have created the new VM, you need to install an OS on it. This OS must be appropriately configured (install drivers, updates and change the system settings). Then generalize the OS for further deployment using Sysprep.
cd %SystemRoot%\System32\Sysprep
sysprep /generalize /oobe /shutdown
Thus, we get a reference VM image.
Now you can remove the VM itself (after saving its VHDX file!!!). To avoid accidentally changing this vhd file, which may crash all child VMs, make it ReadOnly:
Set-ItemProperty f:\vms\vhd\WinSrv2016Base.vhdx -Name IsReadOnly -Value $true
Creating Differencing Disks and VMs on Hyper-V
Now you can create several dependent (child) VHDx files:
New-VHD -ParentPath: f:\vms\vhd\WinSrv2016Base.vhdx -Path f:\vms\vhd\Win2016-diff1.vhdx -Differencing
New-VHD -ParentPath: f:\vms\vhd\WinSrv2016Base.vhdx -Path f:\vms\vhd\Win2016-diff2.vhdx –Differencing
When creating a differencing disk using the graphic interface of Hyper-V Manager, select VHDX-> Differencing as a disk format, specify its name and the path to the parent disk.
Using these VHDx files, create two Hyper-V virtual machines:
New-VM -Name "Win2016-diff1" -Generation 2 -MemoryStartupBytes 1GB -VHDPath f:\vms\vhd\Win2016-diff1.vhdx -SwitchName "External Network"
New-VM -Name "Win2016-diff2" -Generation 2 -MemoryStartupBytes 1GB -VHDPath f:\vms\vhd\Win2016-diff2.vhdx -SwitchName "External Network"
Start them:
Start-VM Win2016-diff*
Merging Differencing Disks in Hyper-V
In Windows 2008 R2 Hyper-V version or higher, it became possible to merge differencing disks with the parent one (or another disk) without stopping the VM. There is a cmdlet to do it: Merge-VHD or a separate option in the Edit menu of the virtual disk in Hyper-V Manager.
Set-ItemProperty f:\vms\vhd\WinSrv2016Base.vhdx -Name IsReadOnly -Value $false
$Merge = @{
Path = ‘f:\vms\vhd\Win2016-diff2.vhdx'
DestinationPath = 'f:\vms\vhd\Win2016.vhdx'
}
Merge-VHD @Merge
To reduce the load of the disk subsystem by multiple access to one parent vhd file from all VMs, it is recommended to place it on fast disks. To prevent this file from becoming the common failure point, think of the backup strategies for it.