question

Bhupinder-0398 avatar image
0 Votes"
Bhupinder-0398 asked RichMatheisen-8856 answered

How to get the serial number of the monitors using Powershell?

After a lot of research, try and error, I got a code that could get as close as possible to the monitors serial number but not the actual serial number.

 $Monitors = Get-WmiObject WmiMonitorID -Namespace root\wmi
 $LogFile = "C:\test\monitors.txt"
    
 function Decode {
     If ($args[0] -is [System.Array]) {
         [System.Text.Encoding]::ASCII.GetString($args[0])
     }
     Else {
         "Not Found"
     }
 }
    
 echo "Manufacturer", "Name, Serial"
    
 ForEach ($Monitor in $Monitors) {  
     $Manufacturer = Decode $Monitor.ManufacturerName -notmatch 0
     $Name = Decode $Monitor.UserFriendlyName -notmatch 0
     $Serial = Decode $Monitor.SerialNumberID -notmatch 0
    
     echo "$Manufacturer, $Name, $Serial" >> $LogFile
 }


The name of manufactural is Acer but the code's output is ACR. Regarding the serial number, which I'm more interested, only a few digits matches. Is there another keywords or line of code that I can use to extract the exact (pretty long) serial number?

windows-server-powershell
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

IanXue-MSFT avatar image
0 Votes"
IanXue-MSFT answered

Hi,

The serial number is stored in SerialNumberID. I don't think there are other properties to pull that long serial number.
https://docs.microsoft.com/en-us/windows/win32/wmicoreprov/wmimonitorid#members

ACR is the manufacturer ID of Acer.
https://edid.tv/manufacturer/

Best Regards,
Ian Xue
============================================
If the Answer is helpful, please click "Accept Answer" and upvote it.
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

ErikdeGroot-5933 avatar image
0 Votes"
ErikdeGroot-5933 answered

The code is very nice, but you forgot some brackets:

 $Serial = Decode $Monitor.SerialNumberID -notmatch 0

Should be

 $Serial = Decode ($Monitor.SerialNumberID -notmatch 0)

And that does get rid of the trailing NULL values


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

WeiXinTanCoboworx-6633 avatar image
0 Votes"
WeiXinTanCoboworx-6633 answered someitguy-6752 commented

In case someone is using powershell 7, Get-WmiObject has been deprecated so use Get-CimInstance instead

An example one-liner for getting your external monitor serial number

[System.Text.Encoding]::ASCII.GetString($(Get-CimInstance WmiMonitorID -Namespace root\wmi)[1].SerialNumberID -notmatch 0)





· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Why the complete serial number is not coming through this PS script. for example in Dell TFT it's long serial number approx 18 characters +numbers.
But with the script its pick only 10 or 11 characters/numbers.

0 Votes 0 ·
someitguy-6752 avatar image someitguy-6752 jitenderarora-8931 ·

I was wondering for the same reason.

The solution is the way "-notmatch" works, it's a regex comparison.

The way it is used in the code above, it eliminates every number containing a "0" in it.

The correct part would be:

 -notmatch '^0$'

Which is telling regex match to eliminate only exact matches of "0" (^ = marks the starting position of a string and $ marks the ending position of a string, together it's an exact string match).

0 Votes 0 ·
RichMatheisen-8856 avatar image
0 Votes"
RichMatheisen-8856 answered

I think the problem is the lack of understanding about what the Get-CimInstance WmiMonitorID -Namespace root\wmi)[1].SerialNumberID -notmatch 0 is actually doing.

The "SerialNumberID" property is not a string. It's an object of type byte[] (an array of bytes). The "-notmatch" operator is acting on the individual elements of the byte array, not on the entire value. It will remove items within the byte array representation of the string that match the value of zero, not just the trailing items that match.

The whole set of code in the original poster's question can be replaced by this:

 $LogFile = "c:\Junk\monitors.txt"
 Get-WmiObject WmiMonitorID -Namespace root\wmi |
     ForEach-Object {
         $Manufacturer   = [System.Text.Encoding]::ASCII.GetString($_.ManufacturerName).Trim(0x00)
         $Name           = [System.Text.Encoding]::ASCII.GetString($_.UserFriendlyName).Trim(0x00)
         $Serial         = [System.Text.Encoding]::ASCII.GetString($_.SerialNumberID).Trim(0x00)
         "{0}, {1}, {2}" -f $Manufacturer,$Name,$Serial | Out-File $LogFile
     }

Adding a "Decode" function in place of a copy/paste of the string [System.Text.Encoding]::ASCII.GetString($_. just adds to the complexity and efficiency, and reduces clarity.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.