More on Select-Object
I had a few question on what I meant by “select-object does Change the object type and therefore you lose methods and properties you may expect to be there.” So Here is an example to help clarify.
First let me show the object type Change
IsPublic IsSerial Name BaseType
——– ——– —- ——–
True True DirectoryInfo System.IO.FileSystemInfo
27# ($dir = Get-item C:\temp | select-Object Fullname,Name,Parent).Gettype()
IsPublic IsSerial Name BaseType
——– ——– —- ——–
True False PSCustomObject System.Object
Even if you specifiy PSBASE you have new object type.
IsPublic IsSerial Name BaseType
——– ——– —- ——–
True True DirectoryInfo System.IO.FileSystemInfo
29# ($dir = Get-item C:\temp | select-Object Fullname,Name,Parent).psbase.Gettype()
IsPublic IsSerial Name BaseType
——– ——– —- ——–
True False PSCustomObject System.Object
>/pre>
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.)
<pre lang="posh">
18# get-item c:\temp | Get-Member -MemberType Properties | ft Name
Name
—-
PSChildName
PSDrive
PSIsContainer
PSParentPath
PSPath
PSProvider
Attributes
CreationTime
CreationTimeUtc
Exists
Extension
FullName
LastAccessTime
LastAccessTimeUtc
LastWriteTime
LastWriteTimeUtc
Name
Parent
Root
Mode
ReparsePoint
After piping to Select-Object you now only have 3
Name
—-
FullName
Name
Parent
Now.. methods before “Conversion”
Name
—-
Create
CreateObjRef
CreateSubdirectory
Delete
Equals
GetAccessControl
GetDirectories
GetFiles
GetFileSystemInfos
GetHashCode
GetLifetimeService
GetObjectData
GetType
get_Attributes
get_CreationTime
get_CreationTimeUtc
get_Exists
get_Extension
get_FullName
get_LastAccessTime
get_LastAccessTimeUtc
get_LastWriteTime
get_LastWriteTimeUtc
get_Name
get_Parent
get_Root
InitializeLifetimeService
MoveTo
Refresh
SetAccessControl
set_Attributes
set_CreationTime
set_CreationTimeUtc
set_LastAccessTime
set_LastAccessTimeUtc
set_LastWriteTime
set_LastWriteTimeUtc
ToString
After
Name
—-
Equals
GetHashCode
GetType
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
43# $dir.GetDirectories()
Mode LastWriteTime Length Name
—- ————- —— —-
d—- 5/22/2007 1:58 PM Console
d—- 5/10/2007 4:36 PM test32
44# $dir = Get-Item C:\temp | Select-Object FullName,Name,Parent
45# $dir.GetDirectories()
Method invocation failed because [System.Management.Automation.PSCustomObject] doesn‘t contain a method named ‘GetDirectories‘.
At line:1 char:20
+ $dir.GetDirectories( <<<< )
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 didnt read the help before I used it or I would have seen this excerpt from get-help Select-Object:
[code]
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.
[/code]
tshell :: Jun.15.2007 :: Custom Objects, HowTo, Powershell, Scripting :: No Comments »

I agree. Objects are stripped and would have to be cast to get their type info back.
If the Object is a PS object like PSDrive, however, the type is maintained. All simple types are maintained also.
Your note is well taken. We need to be aware of this to prevent spending time troubleshooting a known deviation.
Thankyou again Brandon.
PS-> The Citrix stuff is excellent.
[...] and a follow up article [...]