Does anyone know how to ask powershell where something is?
For instance "which notepad" and it returns the directory where the notepad.exe is run from according to the current paths.
views:
1243answers:
6This seems to do what you want (i found it on http://huddledmasses.org/powershell-find-path/ )
Function Find-Path($Path, [switch]$All=$false, [Microsoft.PowerShell.Commands.TestPathType]$type="Any")
## You could comment out the function stuff and use it as a script instead, with this line:
# param($Path, [switch]$All=$false, [Microsoft.PowerShell.Commands.TestPathType]$type="Any")
if($(Test-Path $Path -Type $type)) {
return $path
} else {
[string[]]$paths = @($pwd);
$paths += "$pwd;$env:path".split(";")
$paths = Join-Path $paths $(Split-Path $Path -leaf) | ? { Test-Path $_ -Type $type }
if($paths.Length -gt 0) {
if($All) {
return $paths;
} else {
return $paths[0]
}
}
}
throw "Couldn't find a matching path of type $type"
}
Set-Alias find Find-Path
Check this: Powershell Which
The code provided there suggests this:
($Env:Path).Split(";") | Get-ChildItem -filter notepad
I usually just type:
gcm notepad
or
gcm note*
gcm is the default alias for Get-Command.
On my system, gcm note* outputs:
[27] » gcm note*
CommandType Name Definition
----------- ---- ----------
Application notepad.exe C:\WINDOWS\notepad.exe
Application notepad.exe C:\WINDOWS\system32\notepad.exe
Application Notepad2.exe C:\Utils\Notepad2.exe
Application Notepad2.ini C:\Utils\Notepad2.ini
You get the directory and the command that matches what you're looking for.
The very first alias I made once I started customizing my profile in powershell was 'which'.
New-Alias which get-command
To add this to your profile, type this:
"`nNew-Alias which get-command" | add-content $profile
The `n is to ensure it will start as a new line.
Someone pointed out my blog post about "find" ... but although that's great, it's not really "which" since it works with any file(type) and doesn't find cmdlets, functions or aliases ... the built-in Get-Command
should be what you want, but isn't (in v1) because it doesn't sort the output. I wrote a script that sorts Get-Command
... but if you want a strict which-like behavior, you might try modifying it like this:
function which([string]$command) {
begin { $Script:ErrorActionPreference = "SilentlyContinue" }
process {
if(!$_) { $_ = $command }
Microsoft.PowerShell.Core\Get-Command $_ |
sort {
if($_.CommandType -match "ExternalScript|Application") {
1000 + [array]::IndexOf( (Get-Content Env:Path).Split(";"),
[IO.Path]::GetDirectoryName($_.Definition) )
} else {
[int]$_.CommandType
}
} | Select -first 1 # only return the first item
}
}
Hypothetically, you could also modify it to only output the path, instead of the object (which gets formatted as a table), but first of all you'd have to account for functions and cmdlets which don't have paths (eg: the output of which which
) and secondly, it's PowerShell ... objects are good :)
One strange point - "gcm alias" gives an error, and yet "alias" entered as a command works (and lists all aliases). I don't understand why this is - I can't find out what type of thing "alias" is: get-help alias finds the alias provider, but that help doesn't mention using "alias" as a command... (I'm using PowerShell V2 CTP3, if it matters)