Since Microsoft released: KB5022842 a lot of customers has experienced Windows Server 2022 not being able to boot. On vSphere 7 this might be a problem if you have installed the patch at enabled secure boot for the server.
More information is available here: VMware KB90947
If you need to find VM that are running Windows Server 2022 and have enabled Secure Boot it is not that easy.
The problem is that your cannot always be sure that the OS selected for the VM is the OS actually installed in the VM. If for instance you installed Windows Server 2022 before is was officially supported in vSphere you might have chosen Windows Server 2019. So you will need to use the OS name that VMware tools are reporting.
But what is VMware tools is not running. That’s a problem.
The following script will find VMs with Secure Boot enabled that are running Windows Server 2022, but also VM’s where we are not certain because VMware Tools is not running.
Import-Module VMware.PowerCLI
$vCenter = Connect-VIServer <vCenter-FQDN>
Write-Host 'Processing... ("." = Not Windows, "-" = Not Server 2022, "U" = Uncertain, "E" = Server 2022 with Secureboot enabled)'
$vms = @()
foreach ($vm in Get-VM) {
if ($vm.GuestId -like "*windows*") {
if ($vm.ExtensionData.Config.BootOptions.EfiSecureBootEnabled) {
if ($vm.ExtensionData.Guest.ToolsRunningStatus -Like "*not*") {
# Tools are not running Add VM as we cannot be sure
$vms += $vm
Write-Host "U" -NoNewline
} else {
if ($vm.ExtensionData.Guest.GuestFullName -Like "*2022*") {
# We have an issue with this VM
Write-Host "E" -NoNewline
$vms += $vm
} else {
# We should be good here
Write-Host "-" -NoNewline
}
}
} else {
Write-Host "." -NoNewline
}
}
}
Write-Host ""
Function List-VMSecureBootStatus {
param($vms)
$VMNameLength = ($vms | Select-Object @{n="Length";e={$_.Name.Length}} | Measure-Object -Maximum -Property Length).Maximum
$OSFullNameLength = ($vms | Select-Object @{n="Length";e={$_.Guest.OSFullName.Length}} | Measure-Object -Maximum -Property Length).Maximum
$GuestIdLength = ($vms | Select-Object @{n="Length";e={$_.Guest.GuestId.Length}} | Measure-Object -Maximum -Property Length).Maximum
$ConfiguredGuestIdLength = ($vms | Select-Object @{n="Length";e={$_.Guest.ConfiguredGuestId.Length}} | Measure-Object -Maximum -Property Length).Maximum
$RuntimeGuestIdLength = ($vms | Select-Object @{n="Length";e={$_.Guest.RuntimeGuestId.Length}} | Measure-Object -Maximum -Property Length).Maximum
$ToolsRunningStatusLength = ($vms | Select-Object @{n="Length";e={$_.ExtensionData.Guest.ToolsRunningStatus.Length}} | Measure-Object -Maximum -Property Length).Maximum
Write-Host "VMName $(" " * ($VMNameLength - 6)) OSFullName $(" " * ($OSFullNameLength - 10)) GuestId $(" " * ($GuestIdLength - 7)) ConfiguredGuestId $(" " * ($ConfiguredGuestIdLength - 17)) RuntimeGuestId $(" " * ($RuntimeGuestIdLength - 14)) Tools $(" " * ($ToolsRunningStatusLength - 5)) SecureBoot Status"
Write-Host ("-" * ($VMNameLength + $OSFullNameLength + $GuestIdLength + $ConfiguredGuestIdLength + $RuntimeGuestIdLength + $ToolsRunningStatusLength + 12 + 24))
foreach ($vm in $vms) {
$VMName = "$($vm.Name) $(" " * ($VMNameLength - $vm.Name.length))"
$OSFullName = "$($vm.Guest.OSFullName) $(" " * ($OSFullNameLength - $vm.Guest.OSFullName.length))"
$GuestId = "$($vm.Guest.GuestId) $(" " * ($GuestIdLength - $vm.Guest.GuestId.length))"
$ConfiguredGuestId = "$($vm.Guest.ConfiguredGuestId) $(" " * ($ConfiguredGuestIdLength - $vm.Guest.ConfiguredGuestId.length))"
$RuntimeGuestId = "$($vm.Guest.RuntimeGuestId) $(" " * ($RuntimeGuestIdLength - $vm.Guest.RuntimeGuestId.length))"
$ToolsRunningStatus = "$($vm.ExtensionData.Guest.ToolsRunningStatus) $(" " * ($ToolsRunningStatusLength - $vm.ExtensionData.Guest.ToolsRunningStatus.length))"
Write-Host "$VMName $OSFullName $GuestId $ConfiguredGuestId $RuntimeGuestId $ToolsRunningStatus SecureBoot Enabled: $($vm.ExtensionData.Config.BootOptions.EfiSecureBootEnabled)"
}
}
$Uncertain = $vms | Where-Object { $_.ExtensionData.Guest.ToolsRunningStatus -Like "*not*" }
$Certain = $vms | Where-Object { $_.ExtensionData.Guest.ToolsRunningStatus -NotLike "*not*" }
Write-Host "Press a key to list Windows Server 2022 with Secure Boot enabled..."
$null = Read-Host
List-VMSecureBootStatus -vms $certain
Write-Host "Press a key to list Uncertain VMs with Secure Boot enabled..."
$null = Read-Host
List-VMSecureBootStatus -vms $Uncertain
Write-Host ""
Write-Host "Windows Server 2022 Count: $($Uncertain.Count)"
Write-Host "Uncertain VMs Count: $($Certain.Count)"
Write-Host "Combined VMs Count: $($vms.Count)"
Hope this script helps you out somehow. If so please let me know.
Wish I could code remotely close to this.
Thanks a million!