Hyped-up Hyper-V
Time for something a bit different. This blog is about, well, another blog. Specifically, Oliver Kieselbach's recent write up on managing a Hyper-V lab for Intune.
https://oliverkieselbach.com/2020/11/13/working-with-hyper-v-vms-in-an-intune-lab-environment/
If you haven't read it yet, than stop right now and get to it. Oliver Kieselbach is a Microsoft MVP and has a knack for coming up with all kinds of clever scripts and components that make Intune a better place.
One of the first things I did after reading was apply Mr. Kieselbach's script to my own Hyper-V environment, with a few modifications. Instead of building a new VHD every time, I clone a sys-prepped image of Windows 10, depending on the build number. Here is the modified version:
<#
Version: 1.0
Author: Oliver Kieselbach (oliverkieselbach.com)
Script: Create-MyVM.ps1
Description:
The script crates a VM on a Hyper-V host with TPM and starts it including the VMConnect client.
Release notes:
Version 1.0: Original published version.
The script is provided "AS IS" with no warranties.
#>
<# Modification: This version will prompt for the Windows build number and clone a Gold-Master image disk to build the new VM
#>
$VMName = Read-Host -Prompt 'Enter VM name'
$version = Read-Host -Prompt 'Enter Windows build'
if (($CPUCount = Read-Host -Prompt "CPU count? [default=2, Enter]") -eq "") { $CPUCount = 4 }
Copy-Item -Path "F:\Templates\GM-$($version).vhdx" -Destination "F:\Hyper-V\Virtual hard disks\$($VMName).vhdx" -Force | Out-Null
# some definitions for Network and VM storage path
$VMSwitchName = "VNET"
$VhdxPath = "F:\Hyper-V\Virtual hard disks\$VMName.vhdx"
$VMPath = "F:\Hyper-V\Virtual machines\Virtual Machines"
# I'm not usign Enhanced Session Mode, so we can run this once to disable it on the host
#Set-VMHost -EnableEnhancedSessionMode $false
New-VM -Name $VMName -BootDevice VHD -VHDPath $VhdxPath -Path $VMPath -Generation 2 -Switch $VMSwitchName
Set-VM -VMName $VMName -ProcessorCount $CPUCount
Set-VMMemory -VMName $VMName -StartupBytes 4GB -DynamicMemoryEnabled $false
Set-VMSecurity -VMName $VMName -VirtualizationBasedSecurityOptOut $false
Set-VMKeyProtector -VMName $VMName -NewLocalKeyProtector
Enable-VMTPM -VMName $VMName
Enable-VMIntegrationService -VMName $VMName -Name "Guest Service Interface"
Now of course, you'll notice a few other tweaks; no dynamic memory enabled, no auto-start- fairly minor changes. The big difference comes in the line that clones the disk:
Copy-Item -Path "F:\Templates\GM-$($version).vhdx" -Destination "F:\Hyper-V\Virtual hard disks\$($VMName).vhdx" -Force | Out-Null
The $version variable comes from the initial prompt, which becomes GM-$($version). In my case, there are three images: GM-1909, GM-2004, and GM-20H2.
As you can see in the line above, I use the $VMName variable to match the name of the cloned disk to the VM itself.
Why use the image at all? Because most of the time, when I'm building a VM it is for Autopilot enrollment testing. So naturally, one of the first things I need to do is register the VM in my Azure lab. Instead of running the same PowerShell commands every time, I simply download everything I need so it's sitting on the VM:
Install-PackageProvider -Name Nuget -confirm:$false -force
Install-Script -Name Get-WindowsAutopilotinfo -confirm:$false -force
Install-Script -Name Get-AutopilotDiagnostics -confirm:$false -force
Install-Module WindowsAutopilotIntune -confirm:$false -force
You're probably familiar with the first two up there. They're needed for generating the device ID hardware hash. I also pull down Michael Niehaus's Get-AutopilotDiagnostics script so I can quickly troubleshoot an enrollment gone bad.
Finally, the WindowsAutopilotIntune module allows me to use the "-Online" switch in Get-WindowsAutopilotInfo. Instead of generating a hardware hash .CSV, I can just authenticate into Azure and post the device directly to Autopilot.
So when I boot one of my fresh, new VMs, all I need to do is bring up PowerShell and use:
Set-ExecutionPolicy Bypass -Force
Get-WindowsAutopilotInfo -Online
It's a great setup. I can simply remote into my Hyper-V server from any of the PCs in my house and create as many VMs as I need, each one ready for Autopilot.
Again, huge thanks to Oliver Kieselbach for the PowerShell script.