What is the difference between psCustomObject and PSObject?

I’m using PowerGUI script editor and it insists on replacing references of [psCustomObject] with full notation of [Management.Automation.PSObject] which surprisingly produces completely different output during output to pipeline

PS C:\WINDOWS\system32> [pscustomobject].GetHashCode() -eq [Management.Automation.PSObject].GetHashCode()
PS C:\WINDOWS\system32> [Management.Automation.PSObject]@{A="1"; B= "2"; C= "3"}

Name                           Value
----                           -----
C                              3
B                              2
A                              1

PS C:\WINDOWS\system32> [PSCustomObject]@{A="1"; B= "2"; C= "3"}

A                                       B                                       C
-                                       -                                       -
1                                       2                                       3

[pscustomobject] triggers some special behavior in the PowerShell parser (in v3 and later). It has to be done that way, rather than treating it as a normal type literal and casting a hashtable, because hashtables immediately lose the order that their keys were added. (This behavior was added at the same time as the [ordered] @{ } syntax.)

OK, will raise it as bug with PowerGUI team. Thanks.

[PSCustomObject] is a type accelerator. It constructs a PSObject, but does so in a way that results in hash table keys becoming properties. PSCustomObject isn’t an object type per se - it’s a process shortcut. The docs are relatively clear about it (https://msdn.microsoft.com/en-us/library/system.management.automation.pscustomobject(v=vs.85).aspx) - PSCustomObject is a placeholder that’s used when PSObject is called with no constructor parameters.

So you’re not really creating two different things in your examples - you’re creating one thing, using two different processes. When you create just a PSObject, and assign a hash table to it, you’re really just producing a hash table. There’s no interpretation process, as there is when you use the type accelerator instead.