Select-Object is annoying

Oh how I long for a real Select command.  I’m not a SQL-head by any stretch, but I recognize the need for basic set operations like projection.  The language geeks in DevDiv surely do too: witness LINQ, and to some degree, Powershell itself.  However, I argue PS is falling short on this front.

dir | select fullname, lastwritetime

FullName                   LastWriteTime       
--------                   -------------       
C:\Users\rberg\Contacts    2/19/2009 12:34:40 PM
C:\Users\rberg\Desktop     3/24/2009 12:49:31 PM
C:\Users\rberg\Documents   3/23/2009 4:34:23 PM
C:\Users\rberg\Downloads   3/25/2009 6:38:20 PM
C:\Users\rberg\Favorites   2/19/2009 12:34:43 PM
C:\Users\rberg\Links       3/10/2009 3:36:02 PM
C:\Users\rberg\Music       2/19/2009 1:26:36 PM
C:\Users\rberg\Pictures    2/19/2009 1:26:38 PM
C:\Users\rberg\Saved Games 2/19/2009 12:34:40 PM
C:\Users\rberg\Searches    2/19/2009 12:34:49 PM
C:\Users\rberg\Videos      2/19/2009 1:26:39 PM
C:\Users\rberg\.kdiff3rc   3/25/2009 5:23:33 PM
C:\Users\rberg\_lesshst    3/4/2009 3:01:33 PM
 

It looks like it’s doing something useful, right?  But the more I use Powershell, the more it seems like it’s violating its own guidelines like “input & output should be useful objects, not text-based hacks” and “design for the middle of the pipeline.”  Let’s examine what Select-Object really returns. 

PS >dir .\foo.txt | select name | gm

   TypeName: Selected.System.IO.FileInfo

Name        MemberType   Definition                      
----        ----------   ----------                      
Equals      Method       System.Boolean Equals(Object obj)
GetHashCode Method       System.Int32 GetHashCode()      
GetType     Method       System.Type GetType()           
ToString    Method       System.String ToString()        
Name        NoteProperty System.String Name=foo.txt
 

That’s not a Name, that’s something else entirely.  Besides, I get the feeling it’s not being completely honest with me…doesn’t a FileInfo object have more methods?…

PS >(dir .\foo.txt | select name).gettype()

IsPublic IsSerial Name               BaseType
-------- -------- ----               --------
True     False    PSCustomObject     System.Object 

Caught ya!  Liar! 

I wouldn’t mind a little custom magic going on under the hood if it meant more power in the user’s hands.  But in reality, these PSCustomObjects being tossed around seem to be of very little utility.  In almost every case, simply returning the native type (e.g. a System.String in the case of “select name”) would play nicer with the rest of the pipeline.  I understand there’s a tough barrier when you start selecting multiple objects, or when you want lazy evaluation -- but sorry guys, the current solution ain’t it.

To be clear, I want to be able to do stuff like:

$a = dir foo.txt | select lastwritetime
# oops, we don’t have a real DateTime
$b = $a.adddays(1)  

# oops, neither a string nor a ‘name’ property
dir *.exe | select basename | get-process 

# not even the NoteProperties work in a useful manner
dir | select psparentpath | convert-path

# wouldn’t this be cool?  PS already has quasi tuple syntax, after all
$x, $y = dir | select attributes, length

# or this?  assume do-something is a cmdlet that takes 3 strongly typed parameters by position
# and/or by property name
dir | select fullname –as path, versioninfo, isreadonly –as force | do-something

Am I crazy to want these to work?  Anyone know of ongoing work in this area before I waste some hobby time? :)

3 Responses to “Select-Object is annoying”

  1. BUGBUG: poor title » Blog Archive » Fixing consistency issues with Powershell’s filename properties Says:

    [...] BUGBUG: poor title …the same thing we do every night, Pinky… « Select-Object is annoying [...]

  2. Mike Shepard Says:

    I think that in V2 there's a "Get-propertyvalue" cmdlet that does what you're wanting.

  3. RichardB Says:

    Get-PropertyValue is part of the Powershell Community Extensions. The v2 feature you're probably thinking of is the new -Expand switch for Select. Still a far cry from what I /really/ want, but at least I can write scripts without either % { $foo.bar } ugliness or taking a dependency on PSCX.

Leave a Reply