Fixing consistency issues with Powershell’s filename properties
When I decided to bitch about select-object, I used â€œdirâ€ in my examples for a reason: passing filesystem objects around the pipeline is simultaneously one of the most common yet one of the most annoying things you can do in Powershell. Letâ€™s review some built-in cmdlets from the POV of getting the full path to a given file or folder:
|Cmdlet||Input property name accepted on pipeline||Output property name on object sent to pipeline|
|Get-Item, Get-ChildItem, Set-Item||Path||FullName|
|Join-Path, Split-Path, Test-Path||Path||n/a|
* note that the built-in documentation for Resolve-Path is wrong! as of CTP3, itâ€™s claiming the output is a string
Plus, you may be working with 3rd party tools that obey none of the above conventions.
For example, with the TFS Power Tools, Hyung had the foresight to add string to the list of types we can convert to QualifiedItems behind the scenes using extra constructors, but we still donâ€™t support the ValueFromPipelineByPropertyName idiom thatâ€™s needed to make non-trivial filesystem objects flow. Furthermore, the objects we output are native TFS types, which were never designed with Powershell in mind. Most of the time thereâ€™s little overlap between these objects and non-TFS cmdlets, but a big exception is the LocalItem property of the ExtendedItem object returned by â€œtfprop.â€ In hindsight, we should have added a NoteProperty that aliased it to Path. (â€¦or FullName, or Name, depending on whether the PS guys make up their mind :) )
Then there are tools that have nothing at all to do with Powershell. Some sort of wrapper script is going to be required regardless, but without consistency in the kind of input your wrapper can expect, it can get needlessly complex.
My solution to all of the above is outlined below. Time to let the code do the talking:
Who knew that ValueFromPipelineByPropertyName worked on aliases? I didnâ€™t. I thought it would be nice, but since I didnâ€™t see it documented anywhere, my initial sketch for this function used a ton of ugly ParameterSets as a workaround. Somewhere in there I decided to try Aliases; lo and behold, it works! Yay.
This function is useful on its own â€“ if nothing else I use it as a wholesale replacement for resolve-path, whose behavior on UNC paths is bizarre in my opinion â€“ but its real value is as a helper. For example, a couple snippets from my $profile:
I think the PS parser should be smart enough that double-parens are not required in the second example, but oh well. Pretty simple overall, and super convenient. Enjoy!