Equivalent of *Nix 'which' command in PowerShell?

UnixPowershellCommand

Unix Problem Overview


How do I 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.

Unix Solutions


Solution 1 - Unix

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 at the start of the last line is to ensure it will start as a new line.

Solution 2 - Unix

Here is an actual *nix equivalent, i.e. it gives *nix-style output.

Get-Command <your command> | Select-Object -ExpandProperty Definition

Just replace with whatever you're looking for.

PS C:\> Get-Command notepad.exe | Select-Object -ExpandProperty Definition
C:\Windows\system32\notepad.exe

When you add it to your profile, you will want to use a function rather than an alias because you can't use aliases with pipes:

function which($name)
{
    Get-Command $name | Select-Object -ExpandProperty Definition
}

Now, when you reload your profile you can do this:

PS C:\> which notepad
C:\Windows\system32\notepad.exe

Solution 3 - Unix

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.

Solution 4 - Unix

Try this example:

(Get-Command notepad.exe).Path

Solution 5 - Unix

My proposition for the Which function:

function which($cmd) { get-command $cmd | % { $_.Path } }

PS C:\> which devcon

C:\local\code\bin\devcon.exe

Solution 6 - Unix

A quick-and-dirty match to Unix which is

New-Alias which where.exe

But it returns multiple lines if they exist so then it becomes

function which {where.exe command | select -first 1}

Solution 7 - Unix

I like Get-Command | Format-List, or shorter, using aliases for the two and only for powershell.exe:

gcm powershell | fl

You can find aliases like this:

alias -definition Format-List

Tab completion works with gcm.

To have tab list all options at once:

set-psreadlineoption -editmode emacs

Solution 8 - Unix

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

Solution 9 - Unix

Check this PowerShell Which.

The code provided there suggests this:

($Env:Path).Split(";") | Get-ChildItem -filter notepad.exe

Solution 10 - Unix

Try the where command on Windows 2003 or later (or Windows 2000/XP if you've installed a Resource Kit).

BTW, this received more answers in other questions:

Is there an equivalent of 'which' on Windows?

PowerShell equivalent to Unix which command?

Solution 11 - Unix

If you want a comamnd that both accepts input from pipeline or as paramater, you should try this:

function which($name) {
    if ($name) { $input = $name }
    Get-Command $input | Select-Object -ExpandProperty Path
}

copy-paste the command to your profile (notepad $profile).

Examples:

echo clang.exe | which
C:\Program Files\LLVM\bin\clang.exe

❯ which clang.exe
C:\Program Files\LLVM\bin\clang.exe

Solution 12 - Unix

Use:

function Which([string] $cmd) {
  $path = (($Env:Path).Split(";") | Select -uniq | Where { $_.Length } | Where { Test-Path $_ } | Get-ChildItem -filter $cmd).FullName
  if ($path) { $path.ToString() }
}

# Check if Chocolatey is installed
if (Which('cinst.bat')) {
  Write-Host "yes"
} else {
  Write-Host "no"
}

Or this version, calling the original where command.

This version also works better, because it is not limited to bat files:

function which([string] $cmd) {
  $where = iex $(Join-Path $env:SystemRoot "System32\where.exe $cmd 2>&1")
  $first = $($where -split '[\r\n]')
  if ($first.getType().BaseType.Name -eq 'Array') {
    $first = $first[0]
  }
  if (Test-Path $first) {
    $first
  }
}

# Check if Curl is installed
if (which('curl')) {
  echo 'yes'
} else {
  echo 'no'
}

Solution 13 - Unix

I have this which advanced function in my PowerShell profile:

    function which {
    <#
    .SYNOPSIS
    Identifies the source of a PowerShell command.
    .DESCRIPTION
    Identifies the source of a PowerShell command. External commands (Applications) are identified by the path to the executable
    (which must be in the system PATH); cmdlets and functions are identified as such and the name of the module they are defined in
    provided; aliases are expanded and the source of the alias definition is returned.
    .INPUTS
    No inputs; you cannot pipe data to this function.
    .OUTPUTS
    .PARAMETER Name
    The name of the command to be identified.
    .EXAMPLE
    PS C:\Users\Smith\Documents> which Get-Command
    
    Get-Command: Cmdlet in module Microsoft.PowerShell.Core
    
    (Identifies type and source of command)
    .EXAMPLE
    PS C:\Users\Smith\Documents> which notepad
    
    C:\WINDOWS\SYSTEM32\notepad.exe
    
    (Indicates the full path of the executable)
    #>
        param(
        [String]$name
        )
    
        $cmd = Get-Command $name
        $redirect = $null
        switch ($cmd.CommandType) {
            "Alias"          { "{0}: Alias for ({1})" -f $cmd.Name, (. { which $cmd.Definition } ) }
            "Application"    { $cmd.Source }
            "Cmdlet"         { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
            "Function"       { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
            "Workflow"       { "{0}: {1} {2}" -f $cmd.Name, $cmd.CommandType, (. { if ($cmd.Source.Length) { "in module {0}" -f $cmd.Source} else { "from unspecified source" } } ) }
            "ExternalScript" { $cmd.Source }
            default          { $cmd }
        }
    }

Solution 14 - Unix

You can install the which command from https://goprogram.co.uk/software/commands, along with all of the other UNIX commands.

Solution 15 - Unix

If you have scoop you can install a direct clone of which:

scoop install which
which notepad

Solution 16 - Unix

There also always the option of using which. there are actually three ways to access which from Windows powershell, the first (not necessarily the best) wsl -e which command (this requires installation of windows subsystem for Linux and a running distro). B. gnuwin32 which is a port of several gnu binaries in .exe format as standle alone bundled lanunchers option three, install msys2 (cross compiler platform) if you go where it installed in /usr/bin you'll find many many gnu utils that are more up-to-date. most of them work as stand alone exe and can be copied from the bin folder to your home drive somewhere amd added to your PATH.

Solution 17 - Unix

There also always the option of using which. there are actually three ways to access which from Windows powershell

  • The first, (though not the best) is wsl(windows subsystem for linux)
wsl -e which command 

This requires installation of windows subsystem for Linux and a running distro.

  • Next is gnuwin32 which is a port of several gnu binaries in .exe format as standle alone bundled lanunchers

  • Third, install msys2 (cross compiler platform) if you go where it installed in /usr/bin you'll find many many gnu utils that are more up-to-date. most of them work as stand alone exe and can be copied from the bin folder to your home drive somewhere amd added to your PATH.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDevelopingChrisView Question on Stackoverflow
Solution 1 - Unixhalr9000View Answer on Stackoverflow
Solution 2 - UnixpetrsndView Answer on Stackoverflow
Solution 3 - UnixDavid MohundroView Answer on Stackoverflow
Solution 4 - UnixthesqldevView Answer on Stackoverflow
Solution 5 - UnixVortiFredView Answer on Stackoverflow
Solution 6 - UnixChris F CarrollView Answer on Stackoverflow
Solution 7 - Unixjs2010View Answer on Stackoverflow
Solution 8 - UnixNicholasView Answer on Stackoverflow
Solution 9 - UnixtzotView Answer on Stackoverflow
Solution 10 - UnixAnonymousView Answer on Stackoverflow
Solution 11 - UnixAminView Answer on Stackoverflow
Solution 12 - UnixJeromeView Answer on Stackoverflow
Solution 13 - UnixJeff ZeitlinView Answer on Stackoverflow
Solution 14 - UnixGeorge OgdenView Answer on Stackoverflow
Solution 15 - UnixblenderfreakyView Answer on Stackoverflow
Solution 16 - UnixrayiikView Answer on Stackoverflow
Solution 17 - UnixrayiikView Answer on Stackoverflow