Help explaining PSCustomObject

Got help from Copilot with making a script for getting serial number for the monitor.

Anyone can explain what the [PSCustomObject] part does in the script?

Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID |
    ForEach-Object {
        [PSCustomObject]@{
            SerialNumber = if ($_.SerialNumberID) {
                [System.Text.Encoding]::ASCII.GetString($_.SerialNumberID)
            }
            else {
                "No serial number data"
            }
        }
    }

PSCustomObject with the hash table @{ } create an object with only one property “SerialNumber”

The “[PSCustomObject]” turns the hashtable into a “real” object. The object will have property names taken from the hashtables keys, and the property values taken from the keys’ value. That’s somewhat a simplified description though.

I think your question is really “why create a PSCustomObject instead of just a hashtable?”. The answer to that is objects flow through pipelines more cleanly, their properties show up (by default) nicely in a “table” format, you can convert them into JSON, XML, and often CSV formats, and (most importantly), PowerShell cmdlets (USUALLY) expect objects, not hashtables, to be passed to them (since this is a simple explanation, I’m skipping over the use of “splatting”).

What that script is doing is creating a PSCustomObject and sending it into the “SUCCESS” stream (which is by default hooked up to the console).

2 Likes

Is it possible to use a hash table instead of an object?

I suppose that depends on what you want to do with the information. The “answer” would be “yes, maybe”.

Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorID |
    ForEach-Object {
        $h = @{}
        $h.SerialNumber = if ($_.SerialNumberID) {
                            [System.Text.Encoding]::ASCII.GetString($_.SerialNumberID)
                          }
                          else {
                            "No serial number data"
                          }
        Write-Output $h                          
    }
1 Like

Just show it in the console. It has some potential though. Another idea is to run it on several machines on the network and make a inventory of monitors.

The code I showed you yesterday (using just a hash) will work. The hash will, however, not persist once the ForEach-Object block completes. It (the hash) will go out of scope and a new hash with the same name will be created in the next iteration.

1 Like