none
Strange behavior in Powershell

    Question

  • I came across a strange behavior in Powershell:

    PS > $temp = 123 | select nr1, nr2
    PS > $temp
    
    nr1                                                         nr2
    ---                                                         ---

    First I ran these two commands. That resulted in the following:

    PS > $temp | gm
    
    
       TypeName: Selected.System.Int32
    
    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    nr1         NoteProperty  nr1=null
    nr2         NoteProperty  nr2=null

    As you can see the TypeName is set to "Selected.System.Int32". It became strange when I discovered this:

    PS > $temp.GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     False    PSCustomObject                           System.Object

    Now, the TypeName is set to "PSCustomObject". Why is it different?
    Tuesday, January 26, 2010 2:58 PM

Answers

  • this is correct as you only select the properties you want PowerShell has to create a new Custom Object.

    In PowerShell version 2 the typename "selected.system.int32" is given to the custom object to make it possible to deduct from the custom object what the original object was before the select.
    this name is just there to help you, the basic type is still a PSCustomObject

    you can see how this works by looking at the psobject property, that contains a list of typenames

    $temp.psobject.typenames

    Selected.System.Int32
    System.Management.Automation.PSCustomObject
    System.Object

    Greetings MOW
    Tuesday, January 26, 2010 10:15 PM
  • One could wonder how MOW has known about the existence of PSObject member, when you could not see it when you pipe an object to Get-Member:

    PS C:\> $temp | get-member


       TypeName: Selected.System.Int32

    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    nr1         NoteProperty  nr1=null
    nr2         NoteProperty  nr2=null

    You need to use Force parameter to see hidden members:

    PS C:\> $temp | get-member -force


       TypeName: Selected.System.Int32

    Name        MemberType   Definition
    ----        ----------   ----------
    pstypenames CodeProperty System.Collections.ObjectModel.Collection`1[[System.String, mscorlib, Version=2.0.0.0, Cult..
    psadapted   MemberSet    psadapted {ToString, Equals, GetHashCode, GetType}
    psbase      MemberSet    psbase {ToString, Equals, GetHashCode, GetType}
    psextended  MemberSet    psextended {nr1, nr2}
    psobject    MemberSet    psobject {Members, Properties, Methods, ImmediateBaseObject, BaseObject, TypeNames, get_Mem..
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    nr1         NoteProperty  nr1=null
    nr2         NoteProperty  nr2=null

    MOW has used .psobject.typenames, but you could get the same output with pstypenames member:

    PS C:\> $temp.pstypenames
    Selected.System.Int32
    System.Management.Automation.PSCustomObject
    System.Object



    Aleksandar Nikolić http://powershellers.blogspot.com http://twitter.com/alexandair
    Friday, February 19, 2010 11:13 AM

All replies

  • I can't give you an official answer, but you'll notice your type is "selected.system.int32".  That's not a valid .NET Framework class if you check MSDN.  That means PowerShell has created its own customized object.

    I may try to research it...
    Tuesday, January 26, 2010 4:41 PM
    Moderator
  • this is correct as you only select the properties you want PowerShell has to create a new Custom Object.

    In PowerShell version 2 the typename "selected.system.int32" is given to the custom object to make it possible to deduct from the custom object what the original object was before the select.
    this name is just there to help you, the basic type is still a PSCustomObject

    you can see how this works by looking at the psobject property, that contains a list of typenames

    $temp.psobject.typenames

    Selected.System.Int32
    System.Management.Automation.PSCustomObject
    System.Object

    Greetings MOW
    Tuesday, January 26, 2010 10:15 PM
  • Thank you!

    This was very helpful :)
    Wednesday, January 27, 2010 3:00 PM
  • One could wonder how MOW has known about the existence of PSObject member, when you could not see it when you pipe an object to Get-Member:

    PS C:\> $temp | get-member


       TypeName: Selected.System.Int32

    Name        MemberType   Definition
    ----        ----------   ----------
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    nr1         NoteProperty  nr1=null
    nr2         NoteProperty  nr2=null

    You need to use Force parameter to see hidden members:

    PS C:\> $temp | get-member -force


       TypeName: Selected.System.Int32

    Name        MemberType   Definition
    ----        ----------   ----------
    pstypenames CodeProperty System.Collections.ObjectModel.Collection`1[[System.String, mscorlib, Version=2.0.0.0, Cult..
    psadapted   MemberSet    psadapted {ToString, Equals, GetHashCode, GetType}
    psbase      MemberSet    psbase {ToString, Equals, GetHashCode, GetType}
    psextended  MemberSet    psextended {nr1, nr2}
    psobject    MemberSet    psobject {Members, Properties, Methods, ImmediateBaseObject, BaseObject, TypeNames, get_Mem..
    Equals      Method       bool Equals(System.Object obj)
    GetHashCode Method       int GetHashCode()
    GetType     Method       type GetType()
    ToString    Method       string ToString()
    nr1         NoteProperty  nr1=null
    nr2         NoteProperty  nr2=null

    MOW has used .psobject.typenames, but you could get the same output with pstypenames member:

    PS C:\> $temp.pstypenames
    Selected.System.Int32
    System.Management.Automation.PSCustomObject
    System.Object



    Aleksandar Nikolić http://powershellers.blogspot.com http://twitter.com/alexandair
    Friday, February 19, 2010 11:13 AM