虚拟机中PowerShell脚本调用root\wmi:WmiMonitorID报错求助
问题分析与解决方案
报错原因
WmiMonitorID 是依赖物理显示硬件的WMI类,仅在物理机的真实显示驱动中实现。虚拟机的虚拟化显示适配器(比如VMware SVGA、Hyper-V Virtual Display Adapter等)不会暴露这个类,因此调用Get-CimInstance WmiMonitorID -Namespace root\wmi会返回Not supported错误。而Win32_Process这类通用系统类是虚拟机完全兼容的,所以能正常运行。
修复后的脚本
下面的脚本添加了错误捕获,优化了集合操作效率,同时提供了虚拟机环境下的备选查询方案:
function Get-MonitorInfo { function Decode { If ($args[0] -is [System.Array]) { [System.Text.Encoding]::ASCII.GetString($args[0]).Trim([char]0) } } $monitors = [System.Collections.Generic.List[pscustomobject]]::new() try { # 尝试查询物理机专属的WmiMonitorID类 foreach ($mon in Get-CimInstance WmiMonitorID -Namespace root\wmi -ErrorAction Stop ) { $monitors.Add([pscustomobject]@{ Active = $mon.active InstanceName = $mon.InstanceName ManufacturerName = Decode $Mon.ManufacturerName ProductCodeID = Decode $Mon.ProductCodeID SerialNumberID = Decode $Mon.SerialNumberID Userfriendlyname = Decode $Mon.UserFriendlyName }) } } catch [Microsoft.Management.Infrastructure.CimException] { # 虚拟机环境下,使用通用的Win32_DesktopMonitor类查询基础信息 Write-Warning "WmiMonitorID 不支持当前环境,将返回基础显示设备信息" foreach ($mon in Get-CimInstance Win32_DesktopMonitor) { $monitors.Add([pscustomobject]@{ Active = $mon.Available InstanceName = $mon.DeviceID ManufacturerName = $mon.Manufacturer ProductCodeID = $mon.Model SerialNumberID = $mon.SerialNumber Userfriendlyname = $mon.Description }) } } $monitors } Get-MonitorInfo
关键改进点
- 用
[System.Collections.Generic.List[pscustomobject]]替代数组拼接,提升脚本运行效率 - 添加
-ErrorAction Stop和try/catch块,精准捕获虚拟机环境下的CIM异常 - 捕获异常后自动切换到
Win32_DesktopMonitor类,获取虚拟机显示设备的基础信息 - 优化
Decode函数,移除字符串末尾的无效空字符
说明
虚拟机环境下无法获取物理显示器的序列号、产品ID这类硬件专属信息,Win32_DesktopMonitor返回的信息取决于虚拟化平台的实现,部分字段可能为空。
内容的提问来源于stack exchange,提问作者pburgr
相关产品推荐
相关产品推荐

