-as operator does not recognize System.Management.Automation.PSCustomObject instances as such
See original GitHub issueRelated: #5579
Steps to reproduce
# Create a [System.Management.Automation.PSCustomObject]
# Note that you cannot create a System.Management.Automation.PSCustomObject
# instance with `New-Object System.Management.Automation.PSCustomObject ...`.
# [pscustomobject] is actually [psobject] ([System.Management.Automation.PSObject])
$co = [pscustomobject] @{ foo = 'bar' }
$co.GetType().FullName
'---'
# This should be and is $True.
# Note that using `-is [pscustomobject]` is NOT equivalent and while it also returns $True,
# it does so for any object that has an (invisible) extra [psobject] wrapper, due to the identity
# of [pscustomobject] and [psobject]. All objects returned from *cmdlets* have that extra
# wrapper; e.g., `(Get-Item /) -is [pscustomobject]` yields $True also, while the seemingly
# equivalent `[System.IO.DirectoryInfo]::new('/') -is [pscustomobject]` doesn't - see #5579
$co -is [System.Management.Automation.PSCustomObject]
'---'
# The $co -as ... expression should effectively pass $co through, but doesn't.
# Note that using `-as [pscustomobject]` is NOT equivalent - and pointless, because
# it passes *any* object through, given that it is the same as `-as [psobject]`, which is what ALL
# objects in PowerShell are (semi-secretly) wrapped in.
$null -ne ($co -as [System.Management.Automation.PSCustomObject])
Expected behavior
System.Management.Automation.PSCustomObject
---
True
---
True
Actual behavior
System.Management.Automation.PSCustomObject
---
True
---
False # !!
Environment data
PowerShell Core v6.0.0-beta.4 on macOS 10.12.5
PowerShell Core v6.0.0-beta.4 on Ubuntu 16.04.2 LTS
PowerShell Core v6.0.0-beta.4 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Windows PowerShell v5.1.15063.413 on Microsoft Windows 10 Pro (64-bit; v10.0.15063)
Issue Analytics
- State:
- Created 6 years ago
- Comments:20 (17 by maintainers)
Top Results From Across the Web
PowerShell -is operator always matching PSCustomObject ...
Piping objects to ForEach-Object wraps them in a [psobject] instance (as reflected in $_ / $PSItem ), which causes -is [pscustomobject] / -is...
Read more >System.Management.Automation Namespace
Provides information for applications that are not directly executable by PowerShell. ArgumentCompleterAttribute. This attribute is used to specify an ...
Read more >about PSCustomObject - PowerShell
The [pscustomobject] type accelerator was added in PowerShell 3.0. ... The format operator ( -f ) doesn't recognized an array wrapped by ...
Read more >Creating a Class Definition from an Existing Object - Part 2
As you can see, we received an error. The constructor was not able to correctly interpret and accept the full name of System.Management....
Read more >Get-Member - PowerShell Command - PDQ
Learn how to use the Microsoft PowerShell command Get-Member. PDQ breaks down uses of Get-Member with parameters and helpful examples.
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
@markekraus By design or not, the current behavior is unintuitive and likely to cause errors (as I experienced not too long ago). You said it yourself:
PowerShell functionality should be designed for its users, and leaking implementation details, no matter how much they make sense after one has been staring at the C# code, should be avoided wherever possible.
PowerShell tells white lies all the time, to shield us from the disconcerting complexities of the .NET framework and static typing.
And that’s fine and dandy: I loves me the free-flowing, carefree way that types can be thrown around in PowerShell - for the most part, it’s a great experience.
All I ask for is to be lied to consistently, so I can continue to find comfort in the illusion of a simpler world.
If
([pscustomobject] @{ prop = 1 }).GetType().FullName
yields
System.Management.Automation.PSCustomObject
, but([pscustomobject] @{ prop = 1 }) -as [System.Management.Automation.PSCustomObject ]
yields$null
, my head starts spinning.Is a custom object mysteriously not itself? What’s happening?
Granted,
-as [pscustomobject]
does work as expected, but:(a) only because
[pscustomobject]
is really[psobject]
(my head’s RPM are increasing)(b) it is useless, because something like
(Get-Item /) -as [pscustomobject]
is passed through for any object (because, behind the scenes, everything is wrapped in[psobject]
).No one except the architects / maintainers of the language should have to know any of the behind-the-scenes-but-not-fully intricacies mentioned here.