PowerShell / PowerShell/PowerShell

GetType() errors out on PSMemberSet

Open
#19,789 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Needs-Triage
Dominant language
C#
Stars
55.5k
Forks
8.5k
Avg merge
1d 2h
Merged PRs (30d)
88

Description

Prerequisites
Steps to reproduce
  1. Start with https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-pscustomobject?view=powershell-7.3#using-defaultpropertyset-the-long-way
$myObject = [PSCustomObject]@{
PSTypeName = 'My.Object'
Name       = 'Kevin'
Language   = 'PowerShell'
State      = 'Texas'
}
$defaultDisplaySet = 'Name','Language'
$defaultDisplayPropertySet = New-Object System.Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$defaultDisplaySet)
$PSStandardMembers = [System.Management.Automation.PSMemberInfo[]]@($defaultDisplayPropertySet)
$MyObject | Add-Member MemberSet PSStandardMembers $PSStandardMembers
  1. See that the original $PSStandardMembers works when it's still a System.Management.Automation.PSPropertySet, except it strangely doesn't have System.Object as typename
'$PSStandardMembers:'
$PSStandardMembers
'---'
$PSStandardMembers.GetType()
$PSStandardMembers.psobject
  1. See that there is an unexpected error when trying to do the same thing on a pscustomobject where the added variable has been converted to a System.Management.Automation.PSMemberSet. I expect GetType() to work on all objects
'$myObject:'
$myObject.PSStandardMembers
'---'
$myObject.PSStandardMembers.GetType()
$myObject.psobject
$myObject.PSStandardMembers.psobject
  1. I discovered this problem while investigating a similar problem with this $myObject.PSStandardMembers failing to display as Format-List in $myObject.psobject.Members and displaying as the strange string PSStandardMembers {DefaultDisplayPropertySet} instead
Expected behavior
$PSStandardMembers:

ReferencedPropertyNames : {Name, Language}
MemberType              : PropertySet
Value                   : DefaultDisplayPropertySet {Name, Language}
TypeNameOfValue         : System.Management.Automation.PSPropertySet
Name                    : DefaultDisplayPropertySet
IsInstance              : True


---

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSMemberInfo[]                           System.Array


Members             : {int Length {get;}, long LongLength {get;}, int Rank {get;}, System.Object SyncRoot {get;}…}
Properties          : {int Length {get;}, long LongLength {get;}, int Rank {get;}, System.Object SyncRoot {get;}…}
Methods             : {Get, Set, Address, get_Length…}
ImmediateBaseObject : {DefaultDisplayPropertySet {Name, Language}}
BaseObject          : {DefaultDisplayPropertySet {Name, Language}}
TypeNames           : {System.Management.Automation.PSMemberInfo[], System.Array, System.Object}


$myObject:
PSStandardMembers {DefaultDisplayPropertySet}
---

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSMemberInfo[]                           System.Array


Members             : {string Name=Kevin, string Language=PowerShell, string State=Texas, PSStandardMembers {DefaultDisplayPropertySet}…}
Properties          : {string Name=Kevin, string Language=PowerShell, string State=Texas}
Methods             : {ToString, GetType, Equals, GetHashCode}
ImmediateBaseObject : 
BaseObject          : 
TypeNames           : {My.Object, System.Management.Automation.PSCustomObject, System.Object}


Members             : {DefaultDisplayPropertySet {Name, Language}}
Properties          : {[something here]}
Methods             : {[something here]}
ImmediateBaseObject : PSStandardMembers {DefaultDisplayPropertySet}
BaseObject          : PSStandardMembers {DefaultDisplayPropertySet}
TypeNames           : {System.Management.Automation.PSMemberSet, System.Object}


Actual behavior
$PSStandardMembers:

ReferencedPropertyNames : {Name, Language}
MemberType              : PropertySet
Value                   : DefaultDisplayPropertySet {Name, Language}
TypeNameOfValue         : System.Management.Automation.PSPropertySet
Name                    : DefaultDisplayPropertySet
IsInstance              : True


---

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     PSMemberInfo[]                           System.Array


Members             : {int Length {get;}, long LongLength {get;}, int Rank {get;}, System.Object SyncRoot {get;}…}
Properties          : {int Length {get;}, long LongLength {get;}, int Rank {get;}, System.Object SyncRoot {get;}…}
Methods             : {Get, Set, Address, get_Length…}
ImmediateBaseObject : {DefaultDisplayPropertySet {Name, Language}}
BaseObject          : {DefaultDisplayPropertySet {Name, Language}}
TypeNames           : {System.Management.Automation.PSMemberInfo[], System.Array, System.Object}


$myObject:
PSStandardMembers {DefaultDisplayPropertySet}
---
InvalidOperation: Method invocation failed because [System.Management.Automation.PSMemberSet] does not contain a method named 'GetType'.

Members             : {string Name=Kevin, string Language=PowerShell, string State=Texas, PSStandardMembers {DefaultDisplayPropertySet}…}
Properties          : {string Name=Kevin, string Language=PowerShell, string State=Texas}
Methods             : {ToString, GetType, Equals, GetHashCode}
ImmediateBaseObject : 
BaseObject          : 
TypeNames           : {My.Object, System.Management.Automation.PSCustomObject, System.Object}

Members             : {DefaultDisplayPropertySet {Name, Language}}
Properties          : {}
Methods             : {}
ImmediateBaseObject : PSStandardMembers {DefaultDisplayPropertySet}
BaseObject          : PSStandardMembers {DefaultDisplayPropertySet}
TypeNames           : {System.Management.Automation.PSMemberSet}


Error details
Exception             : 
    Type        : System.Management.Automation.RuntimeException
    ErrorRecord : 
        Exception             : 
            Type    : System.Management.Automation.ParentContainsErrorRecordException
            Message : Method invocation failed because [System.Management.Automation.PSMemberSet] does not contain a method named 'GetType'.
            HResult : -2146233087
        TargetObject          : GetType
        CategoryInfo          : InvalidOperation: (GetType:String) [], ParentContainsErrorRecordException
        FullyQualifiedErrorId : MethodNotFound
        InvocationInfo        : 
            ScriptLineNumber : 1
            OffsetInLine     : 1
            HistoryId        : -1
            Line             : $myObject.PSStandardMembers.GetType()
            PositionMessage  : At line:1 char:1
                               + $myObject.PSStandardMembers.GetType()
                               + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            CommandOrigin    : Internal
        ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
    TargetSite  : 
        Name          : InvokeAdaptedMember
        DeclaringType : System.Management.Automation.Language.PSInvokeMemberBinder, System.Management.Automation, Version=7.3.4.500, Culture=neutral, 
PublicKeyToken=31bf3856ad364e35
        MemberType    : Method
        Module        : System.Management.Automation.dll
    Message     : Method invocation failed because [System.Management.Automation.PSMemberSet] does not contain a method named 'GetType'.
    Data        : System.Collections.ListDictionaryInternal
    Source      : System.Management.Automation
    HResult     : -2146233087
    StackTrace  : 
   at System.Management.Automation.Language.PSInvokeMemberBinder.InvokeAdaptedMember(Object obj, String methodName, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
TargetObject          : GetType
CategoryInfo          : InvalidOperation: (GetType:String) [], RuntimeException
FullyQualifiedErrorId : MethodNotFound
InvocationInfo        : 
    ScriptLineNumber : 1
    OffsetInLine     : 1
    HistoryId        : -1
    Line             : $myObject.PSStandardMembers.GetType()
    PositionMessage  : At line:1 char:1
                       + $myObject.PSStandardMembers.GetType()
                       + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    CommandOrigin    : Internal
ScriptStackTrace      : at <ScriptBlock>, <No file>: line 1
Environment data
Name                           Value
----                           -----
PSVersion                      7.3.4
PSEdition                      Core
GitCommitId                    7.3.4
OS                             Linux 6.3.2-surface #1 SMP PREEMPT_DYNAMIC Fri May 12 15:00:39 UTC 2023
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Visuals

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the PSMemberSet GetType() failure using the PowerShell commands in the issue, then start at PSInvokeMemberBinder.InvokeAdaptedMember in the System.Management.Automation stack trace. Trace how PSStandardMembers is exposed on the PSCustomObject and verify that GetType() works while the member metadata remains consistent with the expected output.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, shell
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.