views:

1243

answers:

6

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.

+2  A: 

This 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
Nicholas
+1 for Jaykul's Find-Path script.
Steven Murawski
A: 

Check this: Powershell Which

The code provided there suggests this:

($Env:Path).Split(";") | Get-ChildItem -filter notepad
ΤΖΩΤΖΙΟΥ
+9  A: 

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.

David Mohundro
its a bit messy, but way cleaner than custom functions and arbitrary splits
DevelopingChris
+14  A: 

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.

halr9000
thanks, where do I put this to get it to stick?
DevelopingChris
You can put it in your profile script. More on profiles - http://msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx
Steven Murawski
I edited above to address your question ChanChan
halr9000
+1  A: 

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 :)

Jaykul
A: 

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)

Paul Moore
The reason for this is that "alias" is an automatic alias for "Get-Alias". Any "Get-*" cmdlet or function (!) automatically gets an alias that is the noun, but only if there is not an existing alias or function with that name. So you can call "Get-FooBar" with "FooBar".
JasonMArcher