Skip to content

Should all [psobject] cmdlet parameters be changed to [object]? #5551

@mklement0

Description

@mklement0

From what I understand, [psobject] is an invisible helper type used behind the scenes.

However, some cmdlets do expose that type directly via their -InputObject parameters.

On a related note regarding output: When cmdlets write to the pipeline, the output objects are invariably [psobject]-wrapped:

# A number literal of type [int], for instance, is not [psobject]-wrapped
PS> 1 -is [psobject]
False

# Passing that number literal through Write-Output adds a [psobject] wrapper.
PS> (Write-Output 1) -is [psobject]
True

This extra [psobject] wrapper is typically benign, but on occasion does result in different behavior - see #5579.

Is there a good reason to declare parameters as [psobject] or [psobject[]] - thereby arguably leaking an implementation detail - when [object] and [object[]] should do?

Here's the list of cmdlets that have [psobject] / [psobject[]] parameters as of PowerShell Core v6.0.0-rc:

> $type = [psobject]; Get-Command -pv c | % { if ($_.Parameters) { $_.Parameters.GetEnumerator() } } | % Value |  ? { $_.ParameterType -eq $type } | Select-Object @{ l='Command'; e={ $c }}, @{ l='Parameter'; e='Name'}, @{ l='Type'; e='ParameterType' }

Command              Parameter   Type                                 
-------              ---------   ----                                 
Format-Xml           InputObject System.Management.Automation.PSObject
Get-TypeInfo         InputObject System.Management.Automation.PSObject
Get-TypeName         InputObject System.Management.Automation.PSObject
Write-ErrorString    InputObject System.Management.Automation.PSObject
Write-StdErr         InputObject System.Management.Automation.PSObject
Add-Member           InputObject System.Management.Automation.PSObject
ConvertTo-Csv        InputObject System.Management.Automation.PSObject
ConvertTo-Html       InputObject System.Management.Automation.PSObject
ConvertTo-Xml        InputObject System.Management.Automation.PSObject
Export-Clixml        InputObject System.Management.Automation.PSObject
Export-Csv           InputObject System.Management.Automation.PSObject
ForEach-Object       InputObject System.Management.Automation.PSObject
Format-Custom        InputObject System.Management.Automation.PSObject
Format-Hex           InputObject System.Management.Automation.PSObject
Format-List          InputObject System.Management.Automation.PSObject
Format-Table         InputObject System.Management.Automation.PSObject
Format-Wide          InputObject System.Management.Automation.PSObject
Get-Member           InputObject System.Management.Automation.PSObject
Get-Unique           InputObject System.Management.Automation.PSObject
Group-Object         InputObject System.Management.Automation.PSObject
Invoke-Command       InputObject System.Management.Automation.PSObject
Measure-Command      InputObject System.Management.Automation.PSObject
Measure-Object       InputObject System.Management.Automation.PSObject
New-Event            Sender      System.Management.Automation.PSObject
New-Event            MessageData System.Management.Automation.PSObject
Out-Default          InputObject System.Management.Automation.PSObject
Out-File             InputObject System.Management.Automation.PSObject
Out-Host             InputObject System.Management.Automation.PSObject
Out-Null             InputObject System.Management.Automation.PSObject
Out-String           InputObject System.Management.Automation.PSObject
Register-EngineEvent MessageData System.Management.Automation.PSObject
Register-ObjectEvent InputObject System.Management.Automation.PSObject
Register-ObjectEvent MessageData System.Management.Automation.PSObject
Select-Object        InputObject System.Management.Automation.PSObject
Select-String        InputObject System.Management.Automation.PSObject
Set-ItemProperty     InputObject System.Management.Automation.PSObject
Sort-Object          InputObject System.Management.Automation.PSObject
Start-Job            InputObject System.Management.Automation.PSObject
Tee-Object           InputObject System.Management.Automation.PSObject
Trace-Command        InputObject System.Management.Automation.PSObject
Where-Object         InputObject System.Management.Automation.PSObject

> $type = [psobject[]]; Get-Command -pv c | % { if ($_.Parameters) { $_.Parameters.GetEnumerator() } } | % Value |  ? { $_.ParameterType -eq $type } | Select-Object @{ l='Command'; e={ $c }}, @{ l='Parameter'; e='Name'}, @{ l='Type'; e='ParameterType' }


Command         Parameter        Type                                   
-------         ---------        ----                                   
Add-History     InputObject      System.Management.Automation.PSObject[]
Compare-Object  ReferenceObject  System.Management.Automation.PSObject[]
Compare-Object  DifferenceObject System.Management.Automation.PSObject[]
ConvertFrom-Csv InputObject      System.Management.Automation.PSObject[]
New-Event       EventArguments   System.Management.Automation.PSObject[]
Write-Output    InputObject      System.Management.Automation.PSObject[]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Breaking-Changebreaking change that may affect usersIssue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-No ActivityIssue has had no activity for 6 months or moreWG-Enginecore PowerShell engine, interpreter, and runtime

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions