Is there an equivalent of 'which' on the Windows command line?

ID : 269

viewed : 188

Tags : windowscommand-linepath-variableswindows

Top 5 Answer for Is there an equivalent of 'which' on the Windows command line?

vote vote


Windows Server 2003 and later (i.e. anything after Windows XP 32 bit) provide the where.exe program which does some of what which does, though it matches all types of files, not just executable commands. (It does not match built-in shell commands like cd.) It will even accept wildcards, so where nt* finds all files in your %PATH% and current directory whose names start with nt.

Try where /? for help.

Note that Windows PowerShell defines where as an alias for the Where-Object cmdlet, so if you want where.exe, you need to type the full name instead of omitting the .exe extension. Alternatively, you can set an alias for it:

Set-Alias which where.exe 

Update: Using Get-Command (alias: gcm) is recommended since it's native to PS and will get all command types: aliases, cmdlets, executables, and functions. Example:

gcm notepad* 
vote vote


While later versions of Windows have a where command, you can also do this with Windows XP by using the environment variable modifiers, as follows:

c:\> for %i in (cmd.exe) do @echo.   %~$PATH:i    C:\WINDOWS\system32\cmd.exe  c:\> for %i in (python.exe) do @echo.   %~$PATH:i    C:\Python25\python.exe 

You don't need any extra tools and it's not limited to PATH since you can substitute any environment variable (in the path format, of course) that you wish to use.

And, if you want one that can handle all the extensions in PATHEXT (as Windows itself does), this one does the trick:

@echo off setlocal enableextensions enabledelayedexpansion  :: Needs an argument.  if "x%1"=="x" (     echo Usage: which ^<progName^>     goto :end )  :: First try the unadorned filenmame.  set fullspec= call :find_it %1  :: Then try all adorned filenames in order.  set mypathext=!pathext! :loop1     :: Stop if found or out of extensions.      if "x!mypathext!"=="x" goto :loop1end      :: Get the next extension and try it.      for /f "delims=;" %%j in ("!mypathext!") do set myext=%%j     call :find_it %1!myext!  :: Remove the extension (not overly efficient but it works).  :loop2     if not "x!myext!"=="x" (         set myext=!myext:~1!         set mypathext=!mypathext:~1!         goto :loop2     )     if not "x!mypathext!"=="x" set mypathext=!mypathext:~1!      goto :loop1 :loop1end  :end endlocal goto :eof  :: Function to find and print a file in the path.  :find_it     for %%i in (%1) do set fullspec=%%~$PATH:i     if not "x!fullspec!"=="x" @echo.   !fullspec!     goto :eof 

It actually returns all possibilities but you can tweak it quite easily for specific search rules.

vote vote


Under PowerShell, Get-Command will find executables anywhere in $Env:PATH.

$ Get-Command eventvwr  CommandType   Name          Definition -----------   ----          ---------- Application   eventvwr.exe  c:\windows\system32\eventvwr.exe Application   eventvwr.msc  c:\windows\system32\eventvwr.msc 

And since powershell let's you define aliases, which can be defined like so.

$ sal which gcm   # short form of `Set-Alias which Get-Command` $ which foo ... 

PowerShell commands are not just executable files (.exe, .ps1, etc). They can also be cmdlets, functions, aliases, custom executable suffixes set in $Env:PATHEXT, etc. Get-Command is able to find and list all of these commands (quite akin to Bash's type -a foo). This alone makes it better than where.exe, which.exe, etc which are typically limited to finding just executables.

Finding executables using only part of the name

$ gcm *disk*  CommandType     Name                             Version    Source -----------     ----                             -------    ------ Alias           Disable-PhysicalDiskIndication    Storage Alias           Enable-PhysicalDiskIndication    Storage Function        Add-PhysicalDisk           Storage Function        Add-VirtualDiskToMaskingSet    Storage Function        Clear-Disk                 Storage Cmdlet          Get-PmemDisk               PersistentMemory Cmdlet          New-PmemDisk               PersistentMemory Cmdlet          Remove-PmemDisk            PersistentMemory Application     diskmgmt.msc               C:\WINDOWS\system32\diskmgmt.msc Application     diskpart.exe                     10.0.17... C:\WINDOWS\system32\diskpart.exe Application     diskperf.exe                     10.0.17... C:\WINDOWS\system32\diskperf.exe Application     diskraid.exe                     10.0.17... C:\WINDOWS\system32\diskraid.exe ... 

Finding custom executables

Unlike UNIX, where executables are files with the executable (+x) bit set, executables on windows are files present in one of the directories specified in the $PATH env. variable whose filename suffixes are named in the $PATHEXT env. variable (defaults to .COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL).

As Get-Command also honours this env. variable, it can be extended to list custom executables. e.g.

$ $Env:PATHEXT="$Env:PATHEXT;.dll;.ps1;.psm1;.py"     # temporary assignment, only for this shell's process  $ gcm user32,kernel32,*WASM*,*http*py  CommandType     Name                        Version    Source -----------     ----                        -------    ------ ExternalScript  Invoke-WASMProfiler.ps1                C:\WINDOWS\System32\WindowsPowerShell\v1.0\Invoke-WASMProfiler.ps1 Application        C:\Users\ME\AppData\Local\Microsoft\WindowsApps\ Application     kernel32.dll                10.0.17... C:\WINDOWS\system32\kernel32.dll Application     user32.dll                  10.0.17... C:\WINDOWS\system32\user32.dll 

See Get-Command for more options and examples.

vote vote


In Windows PowerShell:

set-alias which where.exe 
vote vote


If you have PowerShell installed (which I recommend), you can use the following command as a rough equivalent (substitute programName for your executable's name):

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

More is here: My Manwich! PowerShell Which

Top 3 video Explaining Is there an equivalent of 'which' on the Windows command line?