Skip to content

Commit d7b029a

Browse files
authored
🐛 improve windows hypervisor detection (#5496)
1 parent 779e4a6 commit d7b029a

File tree

3 files changed

+49
-11
lines changed

3 files changed

+49
-11
lines changed

providers/os/id/hypervisor/hypervisor_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,18 @@ func TestHypervisorWindowsWmicGetModel(t *testing.T) {
7575
assert.Equal(t, "VirtualBox", hypervisor)
7676
}
7777

78+
func TestHypervisorWindowsServer2022SMBIOSBIOSVersion(t *testing.T) {
79+
conn, err := mock.New(0, "./testdata/windows_serer_2022_running_hyper_v.toml", &inventory.Asset{})
80+
require.NoError(t, err)
81+
platform, ok := detector.DetectOS(conn)
82+
require.True(t, ok)
83+
84+
hypervisor, ok := subject.Hypervisor(conn, platform)
85+
require.True(t, ok)
86+
87+
assert.Equal(t, "Hyper-V", hypervisor)
88+
}
89+
7890
func TestHypervisorLinuxDmidecode(t *testing.T) {
7991
conn, err := mock.New(0, "./testdata/linux_dmidecode.toml", &inventory.Asset{})
8092
require.NoError(t, err)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[commands."wmic os get * /format:csv"]
2+
stdout = """Node,BootDevice,BuildNumber,BuildType,Caption,CodeSet,CountryCode,CreationClassName,CSCreationClassName,CSDVersion,CSName,CurrentTimeZone,DataExecutionPrevention_32BitApplications,DataExecutionPrevention_Available,DataExecutionPrevention_Drivers,DataExecutionPrevention_SupportPolicy,Debug,Description,Distributed,EncryptionLevel,ForegroundApplicationBoost,FreePhysicalMemory,FreeSpaceInPagingFiles,FreeVirtualMemory,InstallDate,LargeSystemCache,LastBootUpTime,LocalDateTime,Locale,Manufacturer,MaxNumberOfProcesses,MaxProcessMemorySize,MUILanguages,Name,NumberOfLicensedUsers,NumberOfProcesses,NumberOfUsers,OperatingSystemSKU,Organization,OSArchitecture,OSLanguage,OSProductSuite,OSType,OtherTypeDescription,PAEEnabled,PlusProductID,PlusVersionNumber,PortableOperatingSystem,Primary,ProductType,RegisteredUser,SerialNumber,ServicePackMajorVersion,ServicePackMinorVersion,SizeStoredInPagingFiles,Status,SuiteMask,SystemDevice,SystemDirectory,SystemDrive,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize,Version,WindowsDirectory
3+
WIN-VM1,\\Device\\HarddiskVolume1,14393,Multiprocessor Free,Microsoft Windows Server 2022 Standard Evaluation,1252,1,Win32_OperatingSystem,Win32_ComputerSystem,,WIN-VM1,-420,TRUE,TRUE,TRUE,3,FALSE,,FALSE,256,2,1629000,1179648,2833804,20180313201557.000000-420,,20180630024418.280385-420,20180630024734.124000-420,0409,Microsoft Corporation,4294967295,137438953344,{en-US},Microsoft Windows Server 2022 Standard Evaluation|C:\\Windows|\\Device\\Harddisk0\\Partition2,0,35,1,79,Virtual Machine,64-bit,1033,272,18,,,,,FALSE,TRUE,3,,00378-00000-00000-AA739,0,0,1179648,OK,272,\\Device\\HarddiskVolume2,C:\\Windows\\system32,C:,,3276340,2096692,10.0.14393,C:\\Windows"""
4+
5+
[commands.a9bba5b30cdf1d9081a05519d8c5f33d1fc7157fc0ed4529905f6f6246581861]
6+
command = "powershell.exe -NoProfile -EncodedCommand JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsAdwBtAGkAYwAgAGMAbwBtAHAAdQB0AGUAcgBzAHkAcwB0AGUAbQAgAGcAZQB0ACAAbQBvAGQAZQBsAA=="
7+
stdout = """Model
8+
Virtual Machine"""
9+
10+
[commands.e95b1c2663517850f70fe12275de440c78fdbd6ad9547788ea06e551b67a8618]
11+
command = "powershell.exe -NoProfile -EncodedCommand JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsARwBlAHQALQBDAGkAbQBJAG4AcwB0AGEAbgBjAGUAIAAtAEMAbABhAHMAcwBOAGEAbQBlACAAVwBpAG4AMwAyAF8AQwBvAG0AcAB1AHQAZQByAFMAeQBzAHQAZQBtACAAfAAgAFMAZQBsAGUAYwB0AC0ATwBiAGoAZQBjAHQAIAAtAEUAeABwAGEAbgBkAFAAcgBvAHAAZQByAHQAeQAgAE0AYQBuAHUAZgBhAGMAdAB1AHIAZQByAA=="
12+
stdout = """Microsoft Corporation"""
13+
14+
[commands.8eb624f6d9b8837df9664a2c15fc2a42f182bcfd91b22d9f85281633ca04934e]
15+
command = "powershell.exe -NoProfile -EncodedCommand JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsARwBlAHQALQBDAGkAbQBJAG4AcwB0AGEAbgBjAGUAIAAtAEMAbABhAHMAcwBOAGEAbQBlACAAVwBpAG4AMwAyAF8AQgBJAE8AUwAgAHwAIABTAGUAbABlAGMAdAAtAE8AYgBqAGUAYwB0ACAALQBFAHgAcABhAG4AZABQAHIAbwBwAGUAcgB0AHkAIABTAE0AQgBJAE8AUwBCAEkATwBTAFYAZQByAHMAaQBvAG4A"
16+
stdout = """Hyper-V UEFI Release v4.0"""
17+

providers/os/id/hypervisor/windows_h.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,30 @@
33

44
package hypervisor
55

6+
import "github.com/rs/zerolog/log"
7+
8+
var windowsDetectionCommands = []string{
9+
// System model is the preferred detection
10+
"wmic computersystem get model",
11+
// Fallback to check the computer manufacturer
12+
"Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer",
13+
// Modern configurations like Windows Server 2022 running Hyper-V return generic data
14+
// so we need a more reliable method, we are going to check the SMBIOSBIOSVersion as
15+
// our last detection
16+
"Get-CimInstance -ClassName Win32_BIOS | Select-Object -ExpandProperty SMBIOSBIOSVersion",
17+
}
18+
619
// detectWindowsHypervisor detects the hypervisor on Windows.
720
func (h *hyper) detectWindowsHypervisor() (string, bool) {
8-
stdout, err := h.RunCommand("wmic computersystem get model")
9-
if err == nil {
10-
if hypervisor, ok := mapHypervisor(stdout); ok {
11-
return hypervisor, ok
21+
for _, command := range windowsDetectionCommands {
22+
stdout, err := h.RunCommand(command)
23+
if err == nil {
24+
if hypervisor, ok := mapHypervisor(stdout); ok {
25+
return hypervisor, ok
26+
}
1227
}
13-
}
1428

15-
// Use PowerShell as fallback
16-
stdout, err = h.RunCommand(
17-
"Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -ExpandProperty Manufacturer",
18-
)
19-
if err == nil {
20-
return mapHypervisor(stdout)
29+
log.Debug().Err(err).Str("command", command).Msg("could not detect hypervisor")
2130
}
2231

2332
return "", false

0 commit comments

Comments
 (0)