Thursday, June 16, 2022

More Hyper-V Troubleshooting Woes - but a script to help

In a previous post, I noted some challenges I faced with Hyper-V. The TL;DR is that Windows Update breaks Hyper-V, often as a result of a new WIndows Insider Build. In that post I explained the basic fix for this issue. 

Jeffrey Snover once pointed out that when Linux guys are faced with an issue for a second time - they create a script. Well - I am now facing this Hyper-V problem more frequently. The root issue is that an Update can break Hyper-V. The solution is to re-create the VMs. Which can be a lot of work.

As I recovered from the previous failure, I started to write a script to so many of the actions. This week, I had ANOTHER update (WSL) that broke Hyper-V. So to recover, I write the script below. I hope you find is useful.

# fixing hyperv
# a script in several parts

# part 1 - remove Hyper-V from Win 11
# run in elevated command prompt

# 1.1 View what is there
Get-windowsoptionalFeature -FeatureName Microsoft-hyper-V* -online |
  Format-Table -Property *Name,State

# 1.2 Remove the Hyper-V optionalfeature  
Get-windowsoptionalFeature -FeatureName Microsoft-hyper-V* -online |
  Disable-WindowsOptionalFeature -Online

# note this pops up a 'do you want to reboot' - say yes/.
# Note the reboot may fail (trying and not succeeding to stop the hyper-V service)

# Step 2. After the reboot from step 1

# 2.1 View Hyper-V Data Folder
$DataBase = "$env:ProgramData\Microsoft\Windows\Hyper-V"
Get-ChildItem -Path $DataBase

# 2.2 Remove the Hyper-V Data
Get-ChildItem -Path $DataBase -recurse |
  Remove-Item -Recurse -Force

# 2.3 Check the features
Get-windowsoptionalFeature -FeatureName Microsoft-hyper-V* -online |
Format-Table -Property *Name,State

# 2.4 Re-Add Hyper-V to Windows and Reboot
Get-WindowsOptionalFeature -FeatureName Microsoft-hyper-V* -online
| Enable-WindowsOptionalFeature -Online

# Reboot

# Step 3 - Creater New Switchs

New-VMSwitch -Name Internal -SwitchType Internal

$NIC = Get-NetAdapter | where {($_.status -eq 'up') -and ($_.Name -notmatch 'vEthernet')}
New-VMswitch -Name External -NetadapterName $Nic.Name -AllowManagementOS:$true

# Step 4 - recreate the VMs

# At this point, you may need to merge any difference disks. So far I have not automated this
# So use the GUI

# Cookham1
$vmbase = 'D:\VMs\Cookham1'
$Vhdx   = "$VMbase\Virtual Hard Disks\Cookham1.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 8gb -Name "Cookham1" -Path $vmbase
Start-VM -VMName 'Cookham1'

# Reskit VMs
# DC1
$vmbase = 'D:\v9\DC1'
$Vhdx   = "$VMbase\dc1.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 8gb -Name DC1 -Path $vmbase
Start-VM -VMName dc1

# DC2
$vmbase = 'D:\v9\DC2'
$Vhdx   = "$VMbase\dc2.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 8gb -Name DC2 -Path $vmbase
Start-VM -VMName DC2

# SRV1
$vmbase = 'D:\v9\SRV1'
$Vhdx   = "$VMbase\SRV1.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 6gb -Name SRV1 -Path $vmbase
Start-VM -VMName SRV1

# SRV2
$vmbase = 'D:\v9\SRV2'
$Vhdx   = "$VMbase\SRV2.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 6gb -Name SRV2 -Path $vmbase
Start-VM -VMName SRV2

$vmbase = 'D:\v9\UKDC1'
$Vhdx   = "$VMbase\UKDC1.vhdx"
New-VM -VHDPath $vhdx -Generation 2 -MemoryStartupBytes 6gb -Name UKDC1 -Path $vmbase
Start-VM -VMName UKDC1

# Step 5. reset networking

# On DC1.DC2 - turn OFF the DHCP serice temporarily!
# Remove all Reservations and zones

# Then On a VM by VM basis:
#   Open the VM'S Hyperv- Settings and remove Nics
#   In the VM, use Device manager, view hidden devices and Remove ALL the Hyper-V NICS
#   In the VM's Settings - add two nics: Internal (Ethernet) and External (Ethernet #2)
#   Re-configure the Internal statisc NIC's IP address (see

# Recreate the DHCP Scopes and reservations and test

# Test internal communicationns (from VM to each DC and server)
Test-NetConnection DC1
Test-NetConnection DC2
Test-NetConnection UKDC1
Test-NetConnection SRV1
Test-NetConnection SRV2