Joshua's Cheatsheets - Batchfile / bat / Windows CMD - Cheatsheet

Word of advice: When PATH doesn't seem to be working (recent updates not showing) there is no harm in restarting, and it often fixes the issue.


What Type Link
SS64 CMD Reference Docs A-Z CMD Index

How to comment?

REM # My Comment

Using variables

SET MYPATH="C:\Users\Joshua"

WARNING: Be careful about wrapping variables in quotes; you can end up accidentally nesting quotes / double quoting.

Global Variables / Macros

Variable Example What
%path% C:\...\progA\bin;C:\...\progB;... Your global path variable
%cd% C:\Users\Joshua The current directory
%ProgramFiles% C:\Program Files Main program files directory
%ProgramFiles(x86)% C:\Program Files (x86) Main x86 program files directory
%date% Wed 09/02/2020 Current date
%time% 12:50:00.86 Current time

Environmental Variables


REM // Set User variable
setx MYPATH "C:\Users\Joshua"

REM // System variable - requires elevated priv
setx MYPATH "C:\Users\Joshua" /M

SETX edits will only take effect in new console sessions, not the current one.

"set" vs "setx"? Set is temporary - variable is set for duration of console session, whereas setx persists the value, even after you close the console.



Capturing Output to Variable

Kind of complicated in Windows...

The popular "trick" seems to be to use:


For details see:

Using the Clipboard in Windows Commands / Batch

Copying to the Clipboard

You can use CLIP to copy anything to the clipboard. For example,

echo "Hello" | CLIP

For more details, see this tutorial page.

Unicode Issues with CLIP

The windows terminal has notorious issues with codepoints above the standard ascii range (e.g. emoji).

The fix for CLIP is the same for as using Unicode with the command prompt in general; change the code page using chcp 65001.

There is a PR I found that is a great illustrative solution - node-copy-and-paste PR #45.

Reading from the Clipboard

Unfortunately, there is no built-in command for reading from the clipboard in Windows, at least in command prompt. There is a tool built-in to PowerShell though; Get-Clipboard.

If you really need this functionality in CMD, you can always execute the Powershell command from command prompt:

powershell -command "Get-Clipboard"
REM # Can pipe or redirect as you please
REM # Example: print clipboard to stdout
powershell -command "Get-Clipboard" | cat

Joining string vars

Same as bash, you can just put them together:

SET strA=Hello
SET strB=World
SET final=%strA% %strB%
echo %final%

Hello World

And you can also put variables inside strings:

SET strA=Hello
echo "%strA% World"

Hello World

How to get system and user vars

  • Get path

    • PATH
    • More readable version

  • Getting user variables

    • can be accessed just by using %varName% syntax
    • echo %JAVA_HOME%


  • Find process by exe name

    • tasklist /FI "IMAGENAME eq Greenshot.exe"
  • Kill process by exe name

    • taskkill /IM {EXE_NAME}

      • Basically same thing as above: tasklist /FI "IMAGENAME eq {EXE_NAME}"
    • Optional: /F for "force"

Output text to file

  • Redirect operator

    • ipconfig /all > output.txt
  • Double redirect for append mode

    • ipconfig /all >> existingOutput.txt

Find executable paths

Use where to find files, as well as global executable / binary paths.

For example, where npm to find which NPM executables are globally registered in the path.

This is roughly equivalent to Unix's / bash's which command.

File Management

Copy files

There are a bunch of built-in tools. In order of online recommendations:

  • Robocopy

    • ss64
    • Basic syntax: ROBOCOPY {src} {dest} {?fileOrGlobPatterns} {?options}
    • Example: ROBOCOPY %cd% "C:\Users\Joshua\Dropbox\web-project" *.json *.html *.js *.md
    • This S/O covers the defaults for which files Robocopy will skip copying; you can use /IT to included tweaked files, and /IS to include same files
  • XCopy
  • Copy

List all files by size (recursive subdir too)

(@For /F "Delims=" %A in ('dir /B/S/A-D') Do @Echo %~fA %~zA) >filelist.txt

List file tree

  • For both files and folders

    • tree /F
  • Pipe to file - use /A for ascii output else file will be garbled

    • tree /F /A > filestructure.txt

Delete files of a certain type within current folder and all subfolders


DEL /S *.docx

REMINDER - even though there is no wildcard at the ends, it still acts like one for some reason. So DEL /S *.qml will delete all .qml files, but also all .qmlc files - see


Remove-Item * -Include *.qml -Recurse | Remove-Item

NOTE - Powershell does not suffer from the above issue - .qml will match .qml and not .qmlc

Verifying Checksums

A built in utility that you can use is CertUtil.

For example:

CertUtil -hashfile my_program.exe SHA256

If you are looking for a GUI approach, check out hashcheck. Or this list of Windows freeware hash programs.

Since CertUtil can only hash files (not piped or stored strings), to check an online file (via cURL), clipboard contents, or any other strings, you would need to temporary save to a file and then pass the file to CertUtil.

curl https://.../myfile.txt > temp
CertUtil -hashfile temp SHA256
DEL temp

If you want to quickly hash / encode strings with a GUI, I highly recommend the CyberChef online tool. Here is an example recipe for SHA256+Base64.


IF / Else

The basics:

If (condition) (do_something) ELSE (do_something_else)

Make sure logic switches are on same line -

This Won't work:

IF EXIST %MyFile% (
	echo "found"
	echo "not found"

This should work:

IF EXIST %MyFile% (
	echo "found"
) ELSE (
	echo "not found"


Else If can be problematic with .bat batch scripts. Might work in CMD, but for BAT, seems most people recommend nested IFs as alternative, or GOTOs. Worked fine for me though, with Win 8

Using the current directory you are in as a variable

  • Simple!

    • echo %cd%
  • Works great for opening current folder with various programs

    • "C:\Program Files\Microsoft VS Code\Code.exe" %cd%
    • Explorer.exe %cd%

Keeping file open after execution

Add this to very end of file:



Automatically receiving calling input

In a .bat file, you can automatically receive and use the input that was provided when the file was called by using %1, %2, and so on.

Asking for input

You can pause your script and ask for input by using this:

set /P {variableName}="Prompt String"
REM Access by using %{variableName}%


set /P name="What is your name? "
echo Good day, %name%!

File permissions

You can use TAKEOWN to take ownership of files.


REM # Folder contents is foo.txt and subfolder ./pics.
REM # We need to take ownership of ./pics
takeown /r /f pics


On Win, you can use MKLink (ss64) to create a symlink to a directory or file.

  • Link to a file:

    • MKlink {symbolicFileName} {realTargetFile}
  • Link to a directory / folder

    • MKlink /D {symbolicDirName} {realTargetDir}

Creating a symlink requires an elevated (with admin rights) console. (Unless using dev mode on Win 10+)

In general, it is best / easiest to always use absolute paths for the targets. You might want to wrap paths in quotes if you are having issues.

If you want to check what a symlink maps to (or just see if there are any in the current dir), you can use:

dir /a, or for just links, dir /aL

Creating Windows Shortcuts with Batch

Windows shortcut files (.lnk) are a very special proprietary file type, completely separate from symlinks. Their proprietary nature, and the fact that many programs open the target instead of the .lnk file itself, make them difficult to both edit and create.

There is essentially no built-in way to easily create shortcut files from the command line in Windows, especially in Win10. You can work around this with third-party utility programs, VB Scripts, or PowerShell.

My recommendation would be to use NirSoft's NirCmd tool, and its shortcut command.


Active Connections, Ports, Etc

The go-to command for listing active connections and listening ports is netstat.

To find info on a specific port, you could use something like netstat -bnao | grep "8080" (or find, if lacking git-bash). You can then go a step further, and take a PID from that output and use tasklist /fi "pid eq PID_from_netstat" to get process info. Or use taskkill /F /PID PID_from_netstat to kill the process.

Markdown Source Last Updated:
Wed Sep 02 2020 19:51:26 GMT+0000 (Coordinated Universal Time)
Markdown Source Created:
Mon Aug 19 2019 17:06:24 GMT+0000 (Coordinated Universal Time)
© 2020 Joshua Tzucker, Built with Gatsby