Posts RSS Comments RSS 253 Posts and 393 Comments till now

blog: More details on Select-Object

I often to get asked what I mean by "Select-Object changes the object type." I believe this one of those things that is easier to illustrate than just explain. First let me show the object type Change
  1. PS> ($dir = Get-item C:\temp).Gettype()
  2.  
  3. IsPublic IsSerial Name BaseType
  4. -------- -------- ---- --------
  5. True True DirectoryInfo System.IO.FileSystemInfo
  6.  
  7. PS> ($dir = Get-item C:\temp | select-Object Fullname,Name,Parent).Gettype()
  8.  
  9. IsPublic IsSerial Name BaseType
  10. -------- -------- ---- --------
  11. True False PSCustomObject System.Object
  12.  
  13. Even if you specifiy PSBASE you have new object type.
  14.  
  15. PS> ($dir = Get-item C:\temp).psbase.Gettype()
  16.  
  17. IsPublic IsSerial Name BaseType
  18. -------- -------- ---- --------
  19. True True DirectoryInfo System.IO.FileSystemInfo
  20.  
  21. PS> ($dir = Get-item C:\temp | select-Object Fullname,Name,Parent).psbase.Gettype()
  22.  
  23. IsPublic IsSerial Name BaseType
  24. -------- -------- ---- --------
  25. True False PSCustomObject System.Object
Now look at what you lose using this method.

First you will notice you have 21 items returned from Get-Member (I only included Properties for simplicity, but methods work the same way.)
  1. PS> get-item C:\temp | Get-Member -MemberType Properties | ft Name
  2.  
  3. Name
  4. ----
  5. PSChildName
  6. PSDrive
  7. PSIsContainer
  8. PSParentPath
  9. PSPath
  10. PSProvider
  11. Attributes
  12. CreationTime
  13. CreationTimeUtc
  14. Exists
  15. Extension
  16. FullName
  17. LastAccessTime
  18. LastAccessTimeUtc
  19. LastWriteTime
  20. LastWriteTimeUtc
  21. Name
  22. Parent
  23. Root
  24. Mode
  25. ReparsePoint
  26.  
  27. ## After piping to Select-Object you now only have 3
  28.  
  29. PS> Get-Item C:\temp | Select-Object Name,Fullname,Parent | Get-Member -MemberType Properties | ft name
  30.  
  31. Name
  32. ----
  33. FullName
  34. Name
  35. Parent
  36.  
  37. ## Now.. methods before "Conversion"
  38.  
  39. PS> Get-item C:\temp | Get-Member -MemberType Methods | ft name
  40.  
  41. Name
  42. ----
  43. Create
  44. CreateObjRef
  45. CreateSubdirectory
  46. Delete
  47. Equals
  48. GetAccessControl
  49. GetDirectories
  50. GetFiles
  51. GetFileSystemInfos
  52. GetHashCode
  53. GetLifetimeService
  54. GetObjectData
  55. GetType
  56. get_Attributes
  57. get_CreationTime
  58. get_CreationTimeUtc
  59. get_Exists
  60. get_Extension
  61. get_FullName
  62. get_LastAccessTime
  63. get_LastAccessTimeUtc
  64. get_LastWriteTime
  65. get_LastWriteTimeUtc
  66. get_Name
  67. get_Parent
  68. get_Root
  69. InitializeLifetimeService
  70. MoveTo
  71. Refresh
  72. SetAccessControl
  73. set_Attributes
  74. set_CreationTime
  75. set_CreationTimeUtc
  76. set_LastAccessTime
  77. set_LastAccessTimeUtc
  78. set_LastWriteTime
  79. set_LastWriteTimeUtc
  80. ToString
  81.  
  82. ## After
  83.  
  84. PS> Get-item C:\temp | select-object FullName,Name,Parent | Get-Member -MemberType Methods | ft name
  85.  
  86. Name
  87. ----
  88. Equals
  89. GetHashCode
  90. GetType
  91. ToString
As you can see... Effectively they are all gone on the new object. When I first experienced this.. I thought maybe the methods were just hidden... but try to access them
  1. PS> $dir = Get-Item C:\temp
  2. PS> $dir.GetDirectories()
  3.  
  4. Mode LastWriteTime Length Name
  5. ---- ------------- ------ ----
  6. d---- 5/22/2007 1:58 PM Console
  7. d---- 5/10/2007 4:36 PM test32
  8.  
  9. PS> $dir = Get-Item C:\temp | Select-Object FullName,Name,Parent
  10. PS> $dir.GetDirectories()
  11. Method invocation failed because [System.Management.Automation.PSCustomObject] doesn't contain a method named 'GetDirectories'.
  12. At line:1 char:20
I want to be clear... This is not a bug. Its not even a bad idea. I find it useful, but I think it confuses a lot of people. Like most people I didn't read the help before I used it or I would have seen this excerpt from get-help Select-Object:
If you use Select-Object to select specified properties, it copies the values of those properties from the input objects and creates new objects that have the specified properties and copied values.
So, the moral of the story is don't be shocked when your object changes after using Select-Object. Embrace the change :)

Trackback this post | Feed on Comments to this post

Leave a Reply

You must be logged in to post a comment.