Thursday, September 06, 2007

My Manwich! PowerShell Which

One feature I've loved during my brief ventures into Linux-land is the which command, not to be confused with other tasty items. For those not familiar with the command, it enables you to determine the full path to an executable in your environment path that would be executed if only the name of the executable is entered at the command prompt.

This is useful in situations where you have different versions of the same executable on your file system (perhaps even a malicious version) or if you simply want to know where the executable resides. I have often wanted to perform a similar search on my Windows PCs but to the best of my knowledge, the standard command prompt does not provide an easy way to do this.

Gratefully, as is becoming the pattern lately, PowerShell makes this very simple. Simple to the point that I don't really need to bundle it into a function. For example, here is how I locate the SQL Server Management Studio executable that runs when I use Start, Run, "sqlwb":

($Env:Path).Split(";") | Get-ChildItem -filter sqlwb*

If you don't have SQL installed, you can switch the -filter parameter for "calc*" or similar. You can see that it isn't limited to just executable files on your path either and while it doesn't duplicate the default behaviour of the Linux which command, wrapping the one-liner into a function with some extra switches would get it very close.

Monday, September 24, 2007 7:56:02 PM (Cen. Australia Standard Time, UTC+09:30)
The only problems I had with this...
* It returns files with names that start with the parameter, which isn't the same behaviour.
* It doesn't take into account that PowerShell will always choose to execute an alias before a file on the path.

So I added this to my profile. The only niggle I have with it is that if it finds an alias before a "real" file, the formatting that shows directories is lost. But each object in the output is the full *Info instance (AliasInfo or FileInfo), which seems better than just formatting them as strings.

# which for PowerShell
function Get-MatchOnPath($pattern) {
Get-ChildItem alias: -inc $pattern
($Env:Path).Split(";") | Get-ChildItem -filter $pattern* | where {$_.Name -match "$pattern\..*$"}
}

set-alias which Get-MatchOnPath
Adrian Wilkins
Comments are closed.