Virtual Machines on Windows

There's options to create Virtual Machine's (VM's) on a Windows computer, using third-party options such as VMware Workstation, which is a robust, feature-rich product, though this might be out of reach for those on a budget or unnecessary for basic needs. There's also Oracle VM VirtualBox that's a great and open source alternative, which I also used over the years. In this post, we'll focus on Microsoft's own hypervisor technology called Hyper-V

If you have Windows 10 Pro, Education or Enterprise, you can enable Hyper-V at no additional cost or install any third party software, and VM management can be scripted via PowerShell. Be sure to check whether your system supports the following:

  • A 64-bit CPU
  • Virtualization enabled in BIOS, such as Intel VT or AMD-V
  • Adequate disk and RAM to cater for both the host OS and guest VM's

To enable the Hyper-V feature, navigate to Start > Settings > Apps & features > Optional features > More Windows features, ensure all 'Hyper-V' options are checked > select [OK]. A much simpler option is to enable the feature in an elevated PowerShell terminal:


Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All

or within a elevated Command prompt:

DISM /Online /Enable-Feature /All /FeatureName:Microsoft-Hyper-V

In either case, a restart is required to complete the process. Before creating a VM, ask yourself:

  • Do I have the required ISO to install my desired OS?
  • What are the system requirements to run the guest VM?

If you are trialing Windows Server, you have 180 days to run in evaluation mode, which you can re-arm using an elevated Command prompt:


slmgr -rearm

This essentially resets the evaluation up to five times, after which you will need to supply a valid product key or re-create the VM. Windows 10 Enterprise provides 90 days to evaluate. 
With the installation media and system requirements sorted, we can proceed by creating a VM. If you're more comfortable with the UI, open Hyper-V Manager, under Windows Administrative Tools.

In the Hyper-V Manager console, right-click your computer name > New > Virtual Machine... Proceed with the wizard by specifying your VM name and change the location which the VM will be stored if desired, selecting the generation type is important and legacy OS' might only work with Generation 1, whereas modern OS' that support UEFI should work with Generation 2. 

Note: You cannot change the Generation type after creating the VM. However, I have documented a process to change a Generation 2 VM to a Generation 1 type. 


Specify the desired memory size, the virtual switch, default Hyper-V installations will only have one (Default Switch), virtual disk name and size, the installation media drive or ISO, and finally review and select [Finish] to complete the New Virtual Machine wizard.

Using the console to create one or two VM's occasionally is fine, but repetitively this becomes tedious. You can also use PowerShell to create and delete VM's if you'd prefer an automated approach. 

Below I have some PowerShell scripts to create a Generation 1 VM, another to a Generation 2 VM and the last to delete a VM. All of these scripts require an elevated PowerShell terminal or PowerShell ISE to execute and you might need to also set the Execution Policy to Bypass before running these scripts:


Set-ExecutionPolicy -ExecutionPolicy Bypass

Warning: You should always revert back to the Default execution policy as soon as possible, that is Restricted on Windows clients, to eliminate this permissive state being exploited, compromising your computer and environment. Use with caution!


The example below creates a Generation 1 VM, prompting for the VM name, with 1 GB RAM, 2 virtual CPU's, 30 GB virtual disk, connecting to the Default Switch, using a Debian 10 ISO to boot from and will immediately start the VM upon creation: 

Set-Location -Path C:
Clear-Host
Write-Host "New-VM creation script" -foreground yellow
$VM = Read-Host -Prompt 'Enter VM Name'
New-VM -NewVHDPath C:\Hyper-V\$VM\$VM.vhdx -NewVHDSizeBytes 30GB -BootDevice CD -Generation 1 -MemoryStartupBytes 1GB -Name $VM -Path C:\Hyper-V -SwitchName "Default Switch" 
Set-VMProcessor -VMName $VM -Count 2
Set-VM -Name $VM -AutomaticCheckpointsEnabled $false
Set-VMMemory -VMName $VM -DynamicMemoryEnabled $false
Set-VMDvdDrive -VMName $VM -Path C:\Files\ISOs\debian-10.10.0-amd64-netinst.iso
Start-VM -Name $VM
Clear-Host
Write-Host "New-VM creation completed" -foreground green

The example below creates a Generation 2 VM, prompting for the VM name, with 3 GB RAM, 2 virtual CPU's, 30 GB virtual disk, connecting to the Default Switch, using a Windows 10 ISO to boot from, setting the DVD-ROM as the first boot device and will immediately start the VM upon creation: 
 
Set-Location -Path C:
Clear-Host
Write-Host "New-VM creation script" -foreground yellow
$VM = Read-Host -Prompt 'Enter VM Name'
New-VM -NewVHDPath C:\Hyper-V\$VM\$VM.vhdx -NewVHDSizeBytes 30GB -Generation 2 -MemoryStartupBytes 3GB -Name $VM -Path C:\Hyper-V -SwitchName "Default Switch"
Set-VMProcessor -VMName $VM -Count 2
Set-VM -Name $VM -AutomaticCheckpointsEnabled $false
Set-VMMemory -VMName $VM -DynamicMemoryEnabled $false
Add-VMDvdDrive -VMName $VM -Path C:\Files\ISOs\Microsoft\Window10Pro.iso
$VM = Get-VM -Name $VM
$firmware = Get-VMFirmware -VM $VM
$bootorder = $firmware.BootOrder
foreach ($bootdev in $bootorder) {
if ($bootdev.FirmwarePath.Contains("Scsi(0,1)")) {
Set-VMFirmware -FirstBootDevice $bootdev -VM $VM
}
}
Clear-Host
Write-Host "New-VM creation completed" -foreground green
 
Lastly the script below will delete the nominated VM specified in the script:

Clear-Host
Write-Host "Computer deletion script - Use with caution!" -foreground red
$DeletingVM = Read-Host -Prompt 'Enter computer Name'
$ErrorActionPreference = "SilentlyContinue"
$VMPath = "C:\Hyper-V"
VM Clean up
Stop-VM -Name "$DeletingVM" -TurnOff -Force
Remove-VM -Name "$DeletingVM" -Force
Remove-Item $VMPath\$DeletingVM -Recurse
 
Some VM's can take up quite a lot disk space, especially if they are no longer required. By default, virtual disks are dynamically allocated or thinly provisioned, meaning the virtual disk file (or VHD) will only consume what the guest VM utilizes.
Deleting files within the guest VM won't shrink the now inflated VHD, unless you zero out the now freed up disk sectors within the guest VM and compact the associated VHD(s) to reclaim that space.