question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

-as operator does not recognize System.Management.Automation.PSCustomObject instances as such

See original GitHub issue

Related: #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:open
  • Created 6 years ago
  • Comments:20 (17 by maintainers)

github_iconTop GitHub Comments

1reaction
bgshacklettcommented, Mar 14, 2018

@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:

I believe it may be surprising and somewhat confusing to the average PowerShell user.

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.

1reaction
mklement0commented, Mar 9, 2018

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.

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found