如何用PowerShell查询多显示器的分辨率、刷新率等属性?
如何用PowerShell获取每台显示器的分辨率与刷新率属性
需求背景
设备配备2-3台显示器,需获取每台显示器的以下属性:
- HorizontalResolution(水平分辨率)
- VerticalResolution(垂直分辨率)
- MaxRefreshRate(最大刷新率)
- RefreshRate(当前刷新率)
已尝试的方法存在局限:
Get-CimInstance WmiMonitorID -Namespace root\wmi仅能获取部分显示器标识信息,缺少所需的分辨率与刷新率数据- 调用
CIM_MonitorResolution类无报错但无输出 CIM_VideoControllerResolution能拿到分辨率和刷新率,但无法对应到具体显示器
解决方案1:通过WMI/CIM类关联获取
利用Win32_DesktopMonitor与WmiMonitorBasicDisplayParams类的关联,同时遍历CIM_MonitorResolution获取最大刷新率:
# 获取所有显示器的基础信息 $desktopMonitors = Get-CimInstance Win32_DesktopMonitor foreach ($monitor in $desktopMonitors) { # 获取当前显示器的实时分辨率与刷新率 $basicParams = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | Where-Object { $_.InstanceName -match [regex]::Escape($monitor.PNPDeviceID) } # 获取该显示器支持的所有分辨率模式,提取最大刷新率 $supportedResolutions = Get-CimInstance CIM_MonitorResolution | Where-Object { $_.Monitor -like "*$($monitor.DeviceID)*" } $maxRefresh = if ($supportedResolutions) { ($supportedResolutions | Sort-Object MaxRefreshRate -Descending | Select-Object -First 1).MaxRefreshRate } else { "无法获取" } # 输出结构化结果 [PSCustomObject]@{ 显示器名称 = $monitor.Name 水平分辨率 = $basicParams.HorizontalResolution 垂直分辨率 = $basicParams.VerticalResolution 当前刷新率 = $basicParams.CurrentRefreshRate 最大刷新率 = $maxRefresh } }
解决方案2:调用Win32 API直接获取(更可靠)
若WMI类无输出,可通过调用user32.dll的EnumDisplaySettingsAPI获取精确的每台显示器数据:
# 导入Win32 API定义 Add-Type @" using System; using System.Runtime.InteropServices; public class DisplayUtils { [StructLayout(LayoutKind.Sequential)] public struct DEVMODE { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; public short dmSpecVersion; public short dmDriverVersion; public short dmSize; public short dmDriverExtra; public int dmFields; public int dmPositionX; public int dmPositionY; public int dmDisplayOrientation; public int dmDisplayFixedOutput; public short dmColor; public short dmDuplex; public short dmYResolution; public short dmTTOption; public short dmCollate; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmFormName; public short dmLogPixels; public int dmBitsPerPel; public int dmPelsWidth; public int dmPelsHeight; public int dmDisplayFlags; public int dmDisplayFrequency; public int dmICMMethod; public int dmICMIntent; public int dmMediaType; public int dmDitherType; public int dmReserved1; public int dmReserved2; public int dmPanningWidth; public int dmPanningHeight; } [DllImport("user32.dll")] public static extern bool EnumDisplaySettings(string lpszDeviceName, int iModeNum, ref DEVMODE lpDevMode); } "@ # 获取所有显示器的设备名称(去重) $monitorDevices = @() $modeIndex = 0 while ($true) { $devMode = New-Object DisplayUtils+DEVMODE $devMode.dmSize = [System.Runtime.InteropServices.Marshal]::SizeOf($devMode) $success = [DisplayUtils]::EnumDisplaySettings($null, $modeIndex, [ref]$devMode) if (-not $success) { break } if ($devMode.dmDeviceName -notin $monitorDevices) { $monitorDevices += $devMode.dmDeviceName } $modeIndex++ } # 遍历每台显示器,获取当前及最大刷新率 foreach ($device in $monitorDevices) { $currentRes = $null $maxRefresh = 0 $modeIndex = 0 while ($true) { $devMode = New-Object DisplayUtils+DEVMODE $devMode.dmSize = [System.Runtime.InteropServices.Marshal]::SizeOf($devMode) $success = [DisplayUtils]::EnumDisplaySettings($device, $modeIndex, [ref]$devMode) if (-not $success) { break } # 标记当前激活的分辨率模式 if ($devMode.dmFields -band 0x00000040) { # DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY if (-not $currentRes) { $currentRes = [PSCustomObject]@{ 显示器设备名 = $device 水平分辨率 = $devMode.dmPelsWidth 垂直分辨率 = $devMode.dmPelsHeight 当前刷新率 = $devMode.dmDisplayFrequency } } if ($devMode.dmDisplayFrequency -gt $maxRefresh) { $maxRefresh = $devMode.dmDisplayFrequency } } $modeIndex++ } if ($currentRes) { $currentRes | Add-Member -MemberType NoteProperty -Name "最大刷新率" -Value $maxRefresh $currentRes } }
内容的提问来源于stack exchange,提问作者Jared Heinrichs
相关产品推荐
相关产品推荐

