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

Bhupinder 41 Reputation points
2021-01-03T21:26:41.217+00:00

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
Windows Server PowerShell
Windows Server: A family of Microsoft server operating systems that support enterprise-level management, data storage, applications, and communications.PowerShell: A family of Microsoft task automation and configuration management frameworks consisting of a command-line shell and associated scripting language.
5,522 questions
{count} votes

Accepted answer
  1. Ian Xue 36,751 Reputation points Microsoft Vendor
    2021-01-04T13:55:52.373+00:00

    Hi,

    The serial number is stored in SerialNumberID. I don't think there are other properties to pull that long serial number.
    https://learn.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.

    0 comments No comments

6 additional answers

Sort by: Most helpful
  1. Rich Matheisen 46,711 Reputation points
    2022-08-11T21:39:06.88+00:00

    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.

    2 people found this answer helpful.

  2. Jordan Jones 5 Reputation points
    2023-03-13T16:40:03.4966667+00:00

    This is my version it gives the full serial number not shortened version and also asks for the hostname

    $computername = Read-Host -Prompt 'Enter Hostname'
    $MonitorsCMD = ""
    If (!$computername)
    {
    $MonitorsCMD = Get-WmiObject WmiMonitorID -Namespace root\wmi
    }
    Else
    {
    $MonitorsCMD = Get-WmiObject WmiMonitorID -Namespace root\wmi -ComputerName $computername
    }
    
    $Monitors = $MonitorsCMD
    $LogFile = "C:\monitors.txt"
    
    #"Manufacturer,Name,Serial" | Out-File $LogFile
    echo "Name, Serial"
    
    For($i=0; $i -le ($Monitors.Count - 1); $i++)
    {
        $nm = $Monitors[$i].UserFriendlyName -notmatch '^0$'
        $Name = ""
        If ($nm -is [System.Array]) {
        For($j=0; $j -le ($nm.Count - 1); $j++)
        {
            $Name = $Name + [char]$nm[$j]
        }
        }
        $sr = $Monitors[$i].SerialNumberID -notmatch '^0$'
        If ($sr -is [System.Array]) {
        $Serial = ""
            For($j=0; $j -le ($sr.Count - 1); $j++)
        {
            $Serial = $Serial + [char]$sr[$j]
        }
        }
    	
    	#"$Name,$Serial" | Out-File $LogFile -append
         echo "$Name, $Serial"
    }
    PAUSE
    
    1 person found this answer helpful.
    0 comments No comments

  3. Erik de Groot 1 Reputation point
    2022-01-10T10:30:58.407+00:00

    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

    0 comments No comments

  4. WeiXin Tan | Coboworx 1 Reputation point
    2022-03-16T14:53:50.12+00:00

    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)
    

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.