You can retrieve monitor manufacturer, model, and serial numbers from remote machines by querying the WmiMonitorID class via Get-WmiObject or Get-CimInstance. This approach leverages Windows Management Instrumentation to access hardware identification data stored in the system registry, enabling efficient remote monitoring without physical access.
Understanding the WMI Namespace
To collect device information remotely, you must understand where Windows stores this specific data. The hardware IDs for connected displays are exposed through theroot\wmi namespace rather than standard CIM classes like Win32_ComputerSystem. Specifically, the WmiMonitorID class contains the fields necessary for your requirements: ManufacturerName, ProductCodeID, and SerialNumberID.
It is important to note that these fields often contain raw hexadecimal or ASCII byte arrays. For example, a manufacturer name might appear as @P instead of "Philips" if not decoded correctly. Understanding this data structure is critical before attempting to parse the output. If you need to automate pairing devices with manufacturers based on this data, consider reviewing our guide on Automating Device-Manufacturer Pairing with PowerShell for context on handling these identifiers programmatically.
Local vs Remote Execution Methods
There are two primary ways to execute these queries depending on your environment and security constraints. The legacy method usesGet-WmiObject, which relies on DCOM (Distributed Component Object Model). While widely supported on older systems, it requires specific firewall rules to be open for RPC traffic. The modern approach uses Get-CimInstance, which utilizes WS-Management (WinRM) over HTTP/HTTPS. This method is generally more secure and easier to configure in modern enterprise environments.
When connecting to remote machines, ensure that WinRM is enabled and configured to accept connections from your management workstation. You can verify this by running Test-WSMan -ComputerName TargetMachine. If this test fails, no amount of scripting will allow you to retrieve the monitor IDs. Additionally, you must have administrative privileges on the target machine to query the root\wmi namespace effectively.
Decoding Manufacturer and Serial Data
The most common pitfall when collecting this data is receiving garbled text. TheManufacturerName and SerialNumberID properties are returned as byte arrays representing ASCII characters. To make this data usable, you must convert these bytes into strings. A simple casting operation often fails because it may include null terminators or non-printable characters.
You should use the [System.Text.Encoding]::ASCII.GetString() method to clean the data. This ensures that only the relevant alphanumeric characters are retained. For instance, if the raw data includes trailing zeros, the string conversion will handle them gracefully if you trim the result. This step is essential for creating clean reports or integrating the data into asset management systems.
Complete Script for Remote Collection
Below is a robust script that connects to one or more remote computers, retrieves the monitor IDs, decodes the byte arrays, and outputs a structured table. This script usesGet-CimInstance for better compatibility with modern Windows versions and supports piping multiple computer names.
$Computers = @("PC01", "PC02")
$Results = foreach ($Comp in $Computers) {
try {
$Monitors = Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID -ComputerName $Comp -ErrorAction Stop
foreach ($Monitor in $Monitors) {
# Decode byte arrays to readable strings
$Mfg = [System.Text.Encoding]::ASCII.GetString($Monitor.ManufacturerName).Trim()
$Prod = [System.Text.Encoding]::ASCII.GetString($Monitor.ProductCodeID).Trim()
$Serial = [System.Text.Encoding]::ASCII.GetString($Monitor.SerialNumberID).Trim()
[PSCustomObject]@{
ComputerName = $Comp
MonitorIndex = $Monitor.InstanceName
Manufacturer = $Mfg
ProductCode = $Prod
SerialNumber = $Serial
}
}
} catch {
Write-Warning "Failed to query $Comp : $_"
}
}
$Results | Format-Table -AutoSize
This script handles errors gracefully using try-catch blocks. If a machine is offline or inaccessible, it logs a warning but continues processing the remaining computers. This is crucial for large-scale monitoring tasks where intermittent connectivity issues are common. The output is formatted as a custom object, allowing you to easily export the results to CSV or XML for further analysis.
Limitations and Best Practices
While this method is effective, it has limitations. Not all monitors report their serial numbers accurately; some may return generic codes or empty strings. Furthermore, virtual machines may not expose physical monitor IDs unless passed through properly. Always validate the data against known hardware inventories to ensure accuracy. For ongoing monitoring, consider scheduling this script using Task Scheduler on a central management server. This allows you to maintain a historical record of connected devices and detect unauthorized changes. If you are interested in enhancing your PowerShell prompts for better interactive debugging during such scripts, check out Automating PowerShell Prompt using Control Sequences with fzf.Frequently Asked Questions
Why do I see strange characters instead of the manufacturer name?
The data is returned as a byte array in ASCII format. You must explicitly convert these bytes using [System.Text.Encoding]::ASCII.GetString() to get readable text. Failing to do so results in seeing raw hex values or garbled symbols.
Can I use this method on Windows 10 Home edition?
Yes, local execution works on all editions. However, remote execution via WinRM may require additional configuration steps that are restricted or unavailable on Home editions compared to Pro or Enterprise.
What if the SerialNumberID is empty?
Many consumer-grade monitors do not store a unique serial number in the EDID chip. In these cases, the field returns an empty byte array. You should handle this by checking if the decoded string is null or empty before relying on it for unique identification.
Is Get-CimInstance faster than Get-WmiObject?
Generally, yes. Get-CimInstance uses WS-Management which is optimized for network traffic and supports streaming results. Get-WmiObject loads the entire object graph into memory, which can be slower and more resource-intensive for large datasets.
How do I filter only for active monitors?
The WmiMonitorID class does not directly indicate activity status. You typically need to correlate this with WmiMonitorBasicDisplayParams or check the display driver status. Combining these queries allows you to distinguish between physically connected but powered-off displays and those currently in use.