
Batch Files
- 1 installs
- 37.5k repo stars
- Updated August 5, 2026
- github/awesome-copilot
batch-files skill documents Expert-level Windows batch file (.
About
batch-files skill documents Expert-level Windows batch file (.bat/.cmd) skill for writing, debugging, and maintaining CMD scripts. Use when asked to "create a batch file", "write a .bat script", "automate a Windows task", "CMD scripting", "batch automation", "scheduled task script", "Windows shell script", or when working with. name: batch-files description: 'Expert-level Windows batch file (.bat/.cmd) skill for writing, debugging, and maintaining CMD scripts. Use when asked to "create a batch file", "write a .bat script", "automate a Windows task", "CMD scripting", "batch automation", "scheduled task script", "Windows shell script", or when working with .bat/.cmd files in the workspace. Covers cmd.exe syntax, environmen
- Expert-level Windows batch file (.
- Use `SETLOCAL` - Prevents variable values from leaking to parent processes.
- Platform-specific setup patterns for batch-files.
- Evidence-backed steps from upstream SKILL.md.
- When-to-use criteria for batch-files versus alternatives.
Batch Files by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,980 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
batch-files capabilities & compatibility
- Capabilities
- batch files quick start · batch files when to use guidance · batch files integration patterns
What batch-files says it does
Creating or editing `.bat` or `.cmd` files
Automating Windows tasks (file operations, deployments, backups)
npx skills add https://github.com/github/awesome-copilot --skill batch-filesAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 37.5k |
| Last updated | August 5, 2026 |
| Repository | github/awesome-copilot ↗ |
How do I use batch-files correctly?
Expert-level Windows batch file (.bat/.cmd) skill for writing, debugging, and maintaining CMD scripts. Use when asked to "create a batch file", "write a .bat script", "automate a Windows task", "CMD s
Who is it for?
Teams implementing batch-files workflows from the catalog.
Skip if: Skip when requirements clearly match a different specialized stack.
When should I use this skill?
User asks about batch-files, expert-level windows batch file (.bat/.cmd) skill for writing, debugging, and maintaining .
What you get
Working batch-files setup with validated configuration and next steps.
Files
Batch Files
A comprehensive skill for creating, editing, debugging, and maintaining Windows batch files (.bat/.cmd) using cmd.exe. Applies to CLI tool development, system administration automation, scheduled tasks, file operations scripting, and PATH-based executable scripts.
When to Use This Skill
- Creating or editing
.bator.cmdfiles - Automating Windows tasks (file operations, deployments, backups)
- Building CLI tools intended for a
bin/folder on PATH - Writing scheduled task scripts (SCHTASKS, Task Scheduler)
- Debugging batch script issues (variable expansion, error levels, quoting)
- Integrating batch scripts with external tools (curl, git, Node.js, Python)
- Scaffolding new batch-based projects with structured templates
Prerequisites
- Windows NT-based OS (Windows 7 or later)
- cmd.exe (built-in)
- Optional: a
bin/directory on PATH for distributing scripts as commands - Optional: PATHEXT configured to include
.BAT;.CMD(default on Windows)
Command Interpretation
cmd.exe processes each line through four stages in order:
1. Variable substitution — %VAR% tokens are replaced with environment variable values. %0–%9 reference batch arguments. %* expands to all arguments. 2. Quoting and escaping — Caret ^ escapes special characters (& | < > ^). Quotation marks prevent interpretation of enclosed special characters. In batch files, %% yields a literal %. 3. Syntax parsing — Lines are split into pipelines (|), compound commands (&, &&, ||), and parenthesized groups ( ). 4. Redirection — > overwrites, >> appends, < reads input, 2> redirects stderr, 2>&1 merges stderr into stdout, >NUL discards output.
Variables
Environment Variables
set _MY_VAR=Hello World
echo %_MY_VAR%
set _MY_VAR=setwith no arguments lists all variablesset _PREFIXlists variables starting with_PREFIX- No spaces around
=—set name = valsets variable"name "to" val"
Special Variables
| Variable | Value |
|---|---|
%CD% | Current directory |
%DATE% | System date (locale-dependent) |
%TIME% | System time HH:MM:SS.mm |
%RANDOM% | Pseudorandom number 0–32767 |
%ERRORLEVEL% | Exit code of last command |
%USERNAME% | Current user name |
%USERPROFILE% | Current user profile path |
%TEMP% / %TMP% | Temporary file directory |
%PATHEXT% | Executable extensions list |
%COMSPEC% | Path to cmd.exe |
Scoping with SETLOCAL / ENDLOCAL
setlocal
set _LOCAL_VAR=scoped value
endlocal
REM _LOCAL_VAR is no longer defined hereTo return a value from a scoped block:
endlocal & set _RESULT=%_LOCAL_VAR%Delayed Expansion
Variables inside parenthesized blocks are expanded at parse time. Use delayed expansion for runtime evaluation:
setlocal EnableDelayedExpansion
set _COUNT=0
for /l %%i in (1,1,5) do (
set /a _COUNT+=1
echo !_COUNT!
)
endlocal!VAR!expands at execution time (delayed)%VAR%expands at parse time (immediate)
Control Flow
Conditional Execution
if exist "output.txt" echo File found
if not defined _MY_VAR echo Variable not set
if "%_STATUS%"=="ready" (echo Go) else (echo Wait)
if %ERRORLEVEL% neq 0 echo Command failedComparison operators: equ, neq, lss, leq, gtr, geq. Use /i for case-insensitive string comparison.
Compound Commands
command1 & command2 & REM Always run both
command1 && command2 & REM Run command2 only if command1 succeeds
command1 || command2 & REM Run command2 only if command1 failsFOR Loops
REM Iterate over a set of values
for %%i in (alpha beta gamma) do echo %%i
REM Numeric range: start, step, end
for /l %%i in (1,1,10) do echo %%i
REM Files in a directory
for %%f in (*.txt) do echo %%f
REM Recursive file search
for /r %%f in (*.log) do echo %%f
REM Directories only
for /d %%d in (*) do echo %%d
REM Parse command output
for /f "tokens=1,2 delims=:" %%a in ('ipconfig ^| findstr "IPv4"') do echo %%b
REM Parse file lines
for /f "usebackq tokens=*" %%a in ("data.txt") do echo %%aGOTO and Labels
goto :main_logic
:usage
echo Usage: %~nx0 [options]
exit /b 1
:main_logic
echo Running main logic...
goto :eofgoto :eof exits the current batch or subroutine. Labels start with :.
Command-Line Arguments
| Syntax | Value |
|---|---|
%0 | Script name as invoked |
%1–%9 | Positional arguments |
%* | All arguments (unaffected by SHIFT) |
%~1 | Argument 1 with enclosing quotes removed |
%~f1 | Full path of argument 1 |
%~d1 | Drive letter of argument 1 |
%~p1 | Path (without drive) of argument 1 |
%~n1 | File name (no extension) of argument 1 |
%~x1 | Extension of argument 1 |
%~dp0 | Drive and path of the batch file itself |
%~nx0 | File name with extension of the batch file |
%~z1 | File size of argument 1 |
%~$PATH:1 | Search PATH for argument 1 |
Argument Parsing Pattern
:parse_args
if "%~1"=="" goto :args_done
if /i "%~1"=="--help" goto :usage
if /i "%~1"=="--output" (
set "_OUTPUT_DIR=%~2"
shift
)
shift
goto :parse_args
:args_doneString Processing
Substrings
set _STR=Hello World
echo %_STR:~0,5% & REM "Hello"
echo %_STR:~6% & REM "World"
echo %_STR:~-5% & REM "World"
echo %_STR:~0,-6% & REM "Hello"Search and Replace
set _STR=Hello World
echo %_STR:World=Earth% & REM "Hello Earth"
echo %_STR:Hello=% & REM " World" (remove "Hello")Substring Containment Test
if not "%_STR:World=%"=="%_STR%" echo Contains "World"Functions
Functions use labels, CALL, and SETLOCAL/ENDLOCAL:
@echo off
call :greet "Jane Doe"
echo Result: %_GREETING%
exit /b 0
:greet
setlocal
set "_MSG=Hello, %~1"
endlocal & set "_GREETING=%_MSG%"
exit /b 0call :label argsinvokes a functionexit /breturns from the function (not the script)- Use the
endlocal & settrick to pass values out of a scoped block
Arithmetic
set /a performs 32-bit signed integer arithmetic:
set /a _RESULT=10 * 5 + 3
set /a _COUNTER+=1
set /a _REMAINDER=14 %% 3 & REM Use %% for modulo in batch files
set /a _BITS="255 & 0x0F" & REM Bitwise ANDSupported operators: + - * / %% ( ) and bitwise & | ^ ~ << >>.
Hexadecimal (0xFF) and octal (077) literals are supported.
Error Handling
Error Level Conventions
0= success- Non-zero = failure (typically
1)
mycommand.exe
if %ERRORLEVEL% neq 0 (
echo ERROR: mycommand failed with code %ERRORLEVEL%
exit /b %ERRORLEVEL%
)Fail-Fast Pattern
command1 || (echo command1 failed & exit /b 1)
command2 || (echo command2 failed & exit /b 1)Setting Exit Codes
exit /b 0 & REM Return success from a batch/function
exit /b 1 & REM Return failure
cmd /c "exit /b 42" & REM Set ERRORLEVEL to 42 inlineEssential Commands Reference
File Operations
| Command | Purpose |
|---|---|
DIR | List directory contents |
COPY | Copy files |
XCOPY | Extended copy with subdirectories (legacy) |
ROBOCOPY | Robust copy with retry, mirror, logging |
MOVE | Move or rename files |
DEL | Delete files |
REN | Rename files |
MD / MKDIR | Create directories |
RD / RMDIR | Remove directories |
MKLINK | Create symbolic or hard links |
ATTRIB | View or set file attributes |
TYPE | Print file contents |
MORE | Paginated file display |
TREE | Display directory structure |
REPLACE | Replace files in destination with source |
COMPACT | Show or set NTFS compression |
EXPAND | Extract from .cab files |
MAKECAB | Create .cab archives |
TAR | Create or extract tar archives |
Text Search and Processing
| Command | Purpose |
|---|---|
FIND | Search for literal strings |
FINDSTR | Search with limited regular expressions |
SORT | Sort lines alphabetically |
CLIP | Copy piped input to clipboard |
FC | Compare two files |
COMP | Binary file comparison |
CERTUTIL | Encode/decode Base64, compute hashes |
System Information
| Command | Purpose |
|---|---|
SYSTEMINFO | Full system configuration |
HOSTNAME | Display computer name |
VER | Windows version |
WHOAMI | Current user and group info |
TASKLIST | List running processes |
TASKKILL | Terminate processes |
WMIC | WMI queries (drives, OS, memory) |
SC | Service control (query, start, stop) |
DRIVERQUERY | List installed drivers |
REG | Registry operations (query, add, delete) |
SETX | Set persistent environment variables |
Network
| Command | Purpose |
|---|---|
PING | Test network connectivity |
IPCONFIG | IP configuration |
NSLOOKUP | DNS lookup |
NETSTAT | Network connections and ports |
TRACERT | Trace route to host |
NET USE | Map/disconnect network drives |
NET USER | Manage user accounts |
NETSH | Network configuration utility |
ARP | ARP cache management |
ROUTE | Routing table management |
CURL | HTTP requests (Windows 10+) |
SSH | Secure shell (Windows 10+) |
Scheduling and Automation
| Command | Purpose |
|---|---|
SCHTASKS | Create and manage scheduled tasks |
TIMEOUT | Wait N seconds (Vista+) |
START | Launch programs asynchronously |
RUNAS | Run as different user |
SHUTDOWN | Shutdown or restart |
FORFILES | Find files by date and execute commands |
Shell Utilities
| Command | Purpose |
|---|---|
WHERE | Locate executables in PATH |
DOSKEY | Create command macros |
CHOICE | Prompt for single-key input |
MODE | Configure console size and ports |
SUBST | Map folder to drive letter |
CHCP | Get or set console code page |
COLOR | Set console colors |
TITLE | Set console window title |
ASSOC / FTYPE | File type associations |
Shell Syntax and Expressions
Parentheses for Grouping
Parentheses turn compound commands into a single unit for redirection or conditional execution:
(echo Line 1 & echo Line 2) > output.txt
if exist "data.csv" (
echo Processing...
call :process "data.csv"
) else (
echo No data found.
)Escape Characters
The caret ^ escapes the next character:
echo Total ^& Summary & REM Outputs: Total & Summary
echo 100%% complete & REM Outputs: 100% complete (in batch)
echo Line one^
Line two & REM Caret escapes the newlineAfter a pipe, triple caret is needed: echo x ^^^& y | findstr x
Wildcards
*matches any sequence of characters?matches a single character (or zero at end of period-free segment)
dir *.txt & REM All .txt files
ren *.jpeg *.jpg & REM Bulk renameRedirection Summary
command > file.txt & REM Overwrite stdout to file
command >> file.txt & REM Append stdout to file
command 2> errors.log & REM Redirect stderr
command > all.log 2>&1 & REM Merge stderr into stdout
command < input.txt & REM Read stdin from file
command > NUL 2>&1 & REM Discard all outputWriting Production-Quality Batch Files
Standard Script Structure
@echo off
setlocal EnableDelayedExpansion
REM ============================================================
REM Script: example.bat
REM Purpose: Describe what this script does
REM ============================================================
call :main %*
exit /b %ERRORLEVEL%
:main
call :parse_args %*
if not defined _TARGET (
echo ERROR: --target is required. 1>&2
call :usage
exit /b 1
)
echo Processing: %_TARGET%
exit /b 0
:parse_args
if "%~1"=="" exit /b 0
if /i "%~1"=="--target" set "_TARGET=%~2" & shift
if /i "%~1"=="--help" call :usage & exit /b 0
shift
goto :parse_args
:usage
echo Usage: %~nx0 --target ^<path^> [--help]
echo.
echo Options:
echo --target Path to process (required)
echo --help Show this help message
exit /b 0Best Practices
1. Always start with `@echo off` and `setlocal` — Prevents noisy output and variable leakage to the caller. 2. Validate inputs before processing — Check required arguments and file existence early. Use if not defined and if not exist. 3. Quote paths and variables — Use "%~1" and "%_MY_PATH%" to handle spaces and special characters safely. 4. Use `exit /b` instead of `exit` — Avoids closing the parent console window. 5. Return meaningful exit codes — exit /b 0 for success, non-zero for specific failures. 6. Use `%~dp0` for script-relative paths — Ensures the script works regardless of the caller's working directory. 7. Prefer `ROBOCOPY` over `XCOPY` — More reliable, supports retry, mirroring, and logging. 8. Use `EnableDelayedExpansion` when modifying variables inside loops or parenthesized blocks. 9. Write errors to stderr — echo ERROR: message 1>&2 keeps stdout clean for piping. 10. Use `REM` for comments — :: can cause issues inside FOR loop bodies.
Security Considerations
- Never store credentials in batch files — Use environment variables, credential stores, or prompts.
- Validate user input — Unquoted variables containing
&,|, or>can inject commands. Always quote:"%_USER_INPUT%". - Use `SETLOCAL` — Prevents variable values from leaking to parent processes.
- Sanitize file paths — Validate paths before passing to
DEL,RD, orROBOCOPYto prevent unintended deletion. - Avoid `SET /P` for sensitive input — Input is visible and stored in console history. Use a dedicated credential tool when possible.
Debugging and Troubleshooting
| Technique | How |
|---|---|
| Trace execution | Remove @echo off or use @echo on temporarily |
| Step through | Add PAUSE between sections |
| Check error level | echo Exit code: %ERRORLEVEL% after each command |
| Inspect variables | set _MY_ to list all variables starting with _MY_ |
| Delayed expansion issues | Variable inside ( ) block not updating? Enable !VAR! syntax |
FOR loop %% vs % | Use %%i in batch files, %i on the command line |
| Spaces in SET | set name=value not set name = value |
| Caret in pipes | After a pipe, use ^^^ to escape special chars |
| Parentheses in SET /A | Escape with ^( and ^) inside if blocks, or use quotes |
| Double percent for modulo | set /a r=14 %% 3 in batch files |
Cross-Platform and Extended Tools
When batch scripting reaches its limits, these tools extend cmd.exe capabilities:
| Tool | Purpose |
|---|---|
| Cygwin | Full POSIX environment on Windows (grep, sed, awk, ssh) |
| MSYS2 | Lightweight Unix tools and package manager (pacman) |
| WSL | Windows Subsystem for Linux — run native Linux binaries |
| GnuWin32 | Individual GNU utilities as native Windows executables |
| PowerShell | Modern Windows scripting with .NET integration |
Use batch when you need: fast startup, simple file operations, PATH-based CLI tools, or Task Scheduler integration. Consider PowerShell or WSL for complex data processing, REST APIs, or object-oriented scripting.
CMD Keyboard Shortcuts
| Shortcut | Action |
|---|---|
Tab | Auto-complete file/folder names |
Up / Down | Navigate command history |
F7 | Show command history popup |
F3 | Repeat last command |
Esc | Clear current line |
Ctrl+C | Cancel running command |
Alt+F7 | Clear command history |
Reference Files
The references/ folder contains detailed documentation:
| File | Contents |
|---|---|
tools-and-resources.md | Windows tools, utilities, package managers, terminals |
batch-files-and-functions.md | Example scripts, techniques, best practices links |
windows-commands.md | Comprehensive A-Z Windows command reference |
cygwin.md | Cygwin user guide and FAQ |
msys2.md | MSYS2 installation, packages, and environments |
windows-subsystem-on-linux.md | WSL setup, commands, and documentation |
Asset Templates
The assets/ folder contains starter batch file template data, but as text files:
| Template | Purpose |
|---|---|
executable.txt | Standalone CLI tool with argument parsing |
library.txt | Reusable function library with CALL-able labels |
task.txt | Scheduled task / automation script |
@echo off
REM myTool
:: A standalone command-line tool template with argument parsing.
::
:: usage: myTool [options] [1] [2]
:: [1] = input file path or value
:: [2] = output file path (optional)
::
:: options:
:: /? Show this help message
:: -h Show this help message
:: --help Show this help message
:: -v Show version information
:: --verbose Enable verbose output
::
:: examples:
:: > myTool "C:\data\input.txt"
:: > myTool "C:\data\input.txt" "C:\data\output.txt"
:: > myTool --verbose "C:\data\input.txt"
::
set "_helpLinesMyTool=19"
:: ========================================================================
:: TEMPLATE INSTRUCTIONS
:: 1. Find/Replace "myTool" with your executable name (camelCase).
:: 2. Find/Replace "MyTool" with your executable name (PascalCase).
:: 3. Update the help block above (lines 2-19) for your tool.
:: 4. Implement your logic in :_runMyTool.
:: 5. Add any new variables to :_removeBatchVariablesMyTool.
:: ========================================================================
:: Config variables.
set "_versionMyTool=1.0.0"
set "_verboseMyTool=0"
:: Define paths.
set "_scriptDirMyTool=%~dp0"
set "_scriptNameMyTool=%~n0"
:: Parse arguments into variables.
set "_parOneMyTool=%~1"
set "_checkParOneMyTool=-%_parOneMyTool%-"
set "_parTwoMyTool=%~2"
set "_checkParTwoMyTool=-%_parTwoMyTool%-"
set "_parThreeMyTool=%~3"
set "_checkParThreeMyTool=-%_parThreeMyTool%-"
:: -----------------------------------------------------------------------
:: Handle help and version flags.
:: -----------------------------------------------------------------------
if "%_parOneMyTool%"=="/?" call :_showHelpMyTool & goto _removeBatchVariablesMyTool
if /i "%_parOneMyTool%"=="-h" call :_showHelpMyTool & goto _removeBatchVariablesMyTool
if /i "%_parOneMyTool%"=="--help" call :_showHelpMyTool & goto _removeBatchVariablesMyTool
if /i "%_parOneMyTool%"=="-v" (
echo %_scriptNameMyTool% version %_versionMyTool%
goto _removeBatchVariablesMyTool
)
:: -----------------------------------------------------------------------
:: Handle --verbose flag (shift arguments if present).
:: -----------------------------------------------------------------------
if /i "%_parOneMyTool%"=="--verbose" (
set "_verboseMyTool=1"
set "_parOneMyTool=%~2"
set "_checkParOneMyTool=-%~2-"
set "_parTwoMyTool=%~3"
set "_checkParTwoMyTool=-%~3-"
)
:: Create temp directory for intermediate files.
call :_makeTempDirMyTool
:: -----------------------------------------------------------------------
:: Validate required input and start execution.
:: -----------------------------------------------------------------------
if "%_checkParOneMyTool%"=="--" (
echo ERROR: No input specified. Run "%_scriptNameMyTool% /?" for usage. 1>&2
goto _removeBatchVariablesMyTool
)
call :_startMyTool
goto _removeBatchVariablesMyTool
:: ========================================================================
:: MAIN LOGIC
:: ========================================================================
:_startMyTool
if "%_verboseMyTool%"=="1" (
echo [VERBOSE] Input: %_parOneMyTool%
echo [VERBOSE] Output: %_parTwoMyTool%
)
REM Validate input file exists.
if NOT EXIST "%_parOneMyTool%" (
echo ERROR: Input file not found: %_parOneMyTool% 1>&2
goto :eof
)
call :_runMyTool
goto :eof
:_runMyTool
REM ===================================================================
REM TODO: Replace this section with your tool's logic.
REM ===================================================================
echo Processing: %_parOneMyTool%
if NOT "%_checkParTwoMyTool%"=="--" (
echo Output to: %_parTwoMyTool%
REM Example: copy input to output.
REM copy /Y "%_parOneMyTool%" "%_parTwoMyTool%" >nul
)
echo Done.
goto :eof
:: ========================================================================
:: SUPPORT FUNCTIONS
:: ========================================================================
:_showHelpMyTool
echo:
for /f "skip=1 delims=" %%a in ('findstr /n "^" "%~f0"') do (
set "_line=%%a"
setlocal EnableDelayedExpansion
for /f "delims=:" %%n in ("!_line!") do set "_lineNum=%%n"
if !_lineNum! GTR %_helpLinesMyTool% (
endlocal
goto :eof
)
set "_text=!_line:*:=!"
if defined _text (
echo !_text:~4!
) else (
echo:
)
endlocal
)
goto :eof
:_makeTempDirMyTool
set "_tmpDirMyTool=%TEMP%\%~n0_%RANDOM%%RANDOM%"
set "_tmpDirCreatedMyTool=0"
if NOT EXIST "%_tmpDirMyTool%" (
mkdir "%_tmpDirMyTool%" >nul 2>nul
set "_tmpDirCreatedMyTool=1"
)
goto :eof
:: ========================================================================
:: CLEANUP — Remove all batch variables.
:: ========================================================================
:_removeBatchVariablesMyTool
set _helpLinesMyTool=
set _versionMyTool=
set _verboseMyTool=
set _scriptDirMyTool=
set _scriptNameMyTool=
set _parOneMyTool=
set _checkParOneMyTool=
set _parTwoMyTool=
set _checkParTwoMyTool=
set _parThreeMyTool=
set _checkParThreeMyTool=
REM Append new variables above this line.
if "%_tmpDirCreatedMyTool%"=="1" if EXIST "%_tmpDirMyTool%" rmdir /S /Q "%_tmpDirMyTool%" >nul 2>nul
set _tmpDirMyTool=
set _tmpDirCreatedMyTool=
exit /b
@echo off
REM myLib
:: A reusable function library with CALL-able labels.
::
:: usage: call myLib [function] [args...]
:: Functions:
:: trimWhitespace [inputVar] Trim leading/trailing spaces
:: toLower [inputVar] Convert value to lowercase
:: getTimestamp [outputVar] Get current date-time stamp
:: logMessage [level] [message] Write a log entry
:: padRight [string] [width] Right-pad a string with spaces
::
:: examples:
:: > set "myVar= Hello World "
:: > call myLib trimWhitespace myVar
:: > call myLib getTimestamp _now
:: > call myLib logMessage INFO "Acme Corp backup started"
::
set "_helpLinesMyLib=17"
:: ========================================================================
:: TEMPLATE INSTRUCTIONS
:: 1. Find/Replace "myLib" with your library name (camelCase).
:: 2. Find/Replace "MyLib" with your library name (PascalCase).
:: 3. Add your own :_funcNameMyLib labels below.
:: 4. Update the help block above (lines 2-17) for your library.
:: 5. Add any new variables to :_removeBatchVariablesMyLib.
:: ========================================================================
:: Route to the requested function.
set "_funcMyLib=%~1"
set "_argOneMyLib=%~2"
set "_argTwoMyLib=%~3"
set "_argThreeMyLib=%~4"
if "%_funcMyLib%"=="/?" call :_showHelpMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="-h" call :_showHelpMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="--help" call :_showHelpMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="trimWhitespace" call :_trimWhitespaceMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="toLower" call :_toLowerMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="getTimestamp" call :_getTimestampMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="logMessage" call :_logMessageMyLib & goto _removeBatchVariablesMyLib
if /i "%_funcMyLib%"=="padRight" call :_padRightMyLib & goto _removeBatchVariablesMyLib
echo ERROR: Unknown function "%_funcMyLib%". Run "%~n0 /?" for usage.
goto _removeBatchVariablesMyLib
:: ========================================================================
:: LIBRARY FUNCTIONS
:: ========================================================================
:_trimWhitespaceMyLib
REM Trim leading and trailing spaces from a variable.
REM %_argOneMyLib% = name of the variable to trim (passed by name).
if not defined _argOneMyLib goto :eof
setlocal EnableDelayedExpansion
set "_valMyLib=!%_argOneMyLib%!"
REM Trim leading spaces.
for /f "tokens=* delims= " %%a in ("!_valMyLib!") do set "_valMyLib=%%a"
REM Trim trailing spaces.
:_trimTrailingMyLib
if "!_valMyLib:~-1!"==" " (
set "_valMyLib=!_valMyLib:~0,-1!"
goto _trimTrailingMyLib
)
endlocal & set "%_argOneMyLib%=%_valMyLib%"
goto :eof
:_toLowerMyLib
REM Convert a variable's value to lowercase.
REM %_argOneMyLib% = name of the variable to convert (passed by name).
if not defined _argOneMyLib goto :eof
setlocal EnableDelayedExpansion
set "_valMyLib=!%_argOneMyLib%!"
set "_valMyLib=!_valMyLib:A=a!"
set "_valMyLib=!_valMyLib:B=b!"
set "_valMyLib=!_valMyLib:C=c!"
set "_valMyLib=!_valMyLib:D=d!"
set "_valMyLib=!_valMyLib:E=e!"
set "_valMyLib=!_valMyLib:F=f!"
set "_valMyLib=!_valMyLib:G=g!"
set "_valMyLib=!_valMyLib:H=h!"
set "_valMyLib=!_valMyLib:I=i!"
set "_valMyLib=!_valMyLib:J=j!"
set "_valMyLib=!_valMyLib:K=k!"
set "_valMyLib=!_valMyLib:L=l!"
set "_valMyLib=!_valMyLib:M=m!"
set "_valMyLib=!_valMyLib:N=n!"
set "_valMyLib=!_valMyLib:O=o!"
set "_valMyLib=!_valMyLib:P=p!"
set "_valMyLib=!_valMyLib:Q=q!"
set "_valMyLib=!_valMyLib:R=r!"
set "_valMyLib=!_valMyLib:S=s!"
set "_valMyLib=!_valMyLib:T=t!"
set "_valMyLib=!_valMyLib:U=u!"
set "_valMyLib=!_valMyLib:V=v!"
set "_valMyLib=!_valMyLib:W=w!"
set "_valMyLib=!_valMyLib:X=x!"
set "_valMyLib=!_valMyLib:Y=y!"
set "_valMyLib=!_valMyLib:Z=z!"
endlocal & set "%_argOneMyLib%=%_valMyLib%"
goto :eof
:_getTimestampMyLib
REM Write a YYYY-MM-DD_HH-MM-SS timestamp into the named variable.
REM %_argOneMyLib% = name of the output variable.
REM NOTE: Uses %DATE% and %TIME% which are locale-dependent. The parsing
REM below assumes US-style format (e.g., "Fri 04/18/2026" or "04/18/2026").
REM Adjust the substring offsets for your locale, or use PowerShell for
REM a locale-independent alternative:
REM for /f %%a in ('powershell -nop -c "Get-Date -F yyyy-MM-dd_HH-mm-ss"') do set "var=%%a"
if not defined _argOneMyLib goto :eof
setlocal EnableDelayedExpansion
REM Parse date — strip leading day name if present (e.g., "Fri ").
set "_dtMyLib=%DATE%"
if "!_dtMyLib:~3,1!"==" " set "_dtMyLib=!_dtMyLib:~4!"
set "_stampMyLib=!_dtMyLib:~6,4!-!_dtMyLib:~0,2!-!_dtMyLib:~3,2!"
REM Parse time — replace leading space with 0 for single-digit hours.
set "_tmMyLib=%TIME: =0%"
set "_stampMyLib=!_stampMyLib!_!_tmMyLib:~0,2!-!_tmMyLib:~3,2!-!_tmMyLib:~6,2!"
endlocal & set "%_argOneMyLib%=%_stampMyLib%"
goto :eof
:_logMessageMyLib
REM Write a timestamped log line to stdout.
REM %_argOneMyLib% = level (INFO, WARN, ERROR)
REM %_argTwoMyLib% = message text
REM NOTE: Uses %DATE% and %TIME% (locale-dependent). See :_getTimestampMyLib.
setlocal EnableDelayedExpansion
set "_dtMyLib=%DATE%"
if "!_dtMyLib:~3,1!"==" " set "_dtMyLib=!_dtMyLib:~4!"
set "_tmMyLib=%TIME: =0%"
set "_tsMyLib=!_dtMyLib:~6,4!-!_dtMyLib:~0,2!-!_dtMyLib:~3,2! !_tmMyLib:~0,2!:!_tmMyLib:~3,2!:!_tmMyLib:~6,2!"
echo [!_tsMyLib!] [%_argOneMyLib%] %_argTwoMyLib%
endlocal
goto :eof
:_padRightMyLib
REM Pad a string to a given width with trailing spaces.
REM %_argOneMyLib% = the string to pad
REM %_argTwoMyLib% = desired total width
if not defined _argOneMyLib goto :eof
if not defined _argTwoMyLib goto :eof
setlocal EnableDelayedExpansion
set "_valMyLib=%_argOneMyLib%"
set "_padMyLib=%_valMyLib% "
set "_padMyLib=!_padMyLib:~0,%_argTwoMyLib%!"
echo !_padMyLib!
endlocal
goto :eof
:: ========================================================================
:: HELP
:: ========================================================================
:_showHelpMyLib
echo:
for /f "skip=1 delims=" %%a in ('findstr /n "^" "%~f0"') do (
set "_line=%%a"
setlocal EnableDelayedExpansion
for /f "delims=:" %%n in ("!_line!") do set "_lineNum=%%n"
if !_lineNum! GTR %_helpLinesMyLib% (
endlocal
goto :eof
)
set "_text=!_line:*:=!"
if defined _text (
echo !_text:~4!
) else (
echo:
)
endlocal
)
goto :eof
:: ========================================================================
:: CLEANUP — Remove all batch variables.
:: ========================================================================
:_removeBatchVariablesMyLib
set _helpLinesMyLib=
set _funcMyLib=
set _argOneMyLib=
set _argTwoMyLib=
set _argThreeMyLib=
set _valMyLib=
REM Append new variables above this line.
exit /b
@echo off
REM myTask
:: An automation script for scheduled or manual task execution.
::
:: usage: myTask [options]
:: [1] = task target or configuration value (optional)
::
:: options:
:: /? Show this help message
:: -h Show this help message
:: --help Show this help message
:: --dry Dry-run mode (preview actions without executing)
::
:: examples:
:: > myTask
:: - Run the default task.
:: > myTask --dry
:: - Preview what the task would do without making changes.
:: > myTask "C:\data\reports"
:: - Run the task against a specific target directory.
::
set "_helpLinesMyTask=20"
:: ========================================================================
:: TEMPLATE INSTRUCTIONS
:: 1. Find/Replace "myTask" with your task name (camelCase).
:: 2. Find/Replace "MyTask" with your task name (PascalCase).
:: 3. Update the help block above (lines 2-20) for your task.
:: 4. Implement your logic in :_runMyTask.
:: 5. Add any new variables to :_removeBatchVariablesMyTask.
:: ========================================================================
:: Config variables.
set "_dryRunMyTask=0"
set "_logFileMyTask=%TEMP%\%~n0.log"
:: Define paths.
set "_scriptDirMyTask=%~dp0"
set "_scriptNameMyTask=%~n0"
:: Parse arguments into variables.
set "_parOneMyTask=%~1"
set "_checkParOneMyTask=-%_parOneMyTask%-"
set "_parTwoMyTask=%~2"
set "_checkParTwoMyTask=-%_parTwoMyTask%-"
:: -----------------------------------------------------------------------
:: Handle help flag.
:: -----------------------------------------------------------------------
if "%_parOneMyTask%"=="/?" call :_showHelpMyTask & goto _removeBatchVariablesMyTask
if /i "%_parOneMyTask%"=="-h" call :_showHelpMyTask & goto _removeBatchVariablesMyTask
if /i "%_parOneMyTask%"=="--help" call :_showHelpMyTask & goto _removeBatchVariablesMyTask
:: -----------------------------------------------------------------------
:: Handle --dry flag (shift arguments if present).
:: -----------------------------------------------------------------------
if /i "%_parOneMyTask%"=="--dry" (
set "_dryRunMyTask=1"
set "_parOneMyTask=%~2"
set "_checkParOneMyTask=-%~2-"
)
:: Store current directory to return to after task completes.
set "_savedDirMyTask=%CD%"
:: Create temp directory for intermediate files.
call :_makeTempDirMyTask
:: -----------------------------------------------------------------------
:: Log start and begin execution.
:: -----------------------------------------------------------------------
call :_logMyTask "=========================================="
call :_logMyTask "Task started: %_scriptNameMyTask%"
call :_logMyTask "=========================================="
call :_runMyTask
call :_logMyTask "Task finished: %_scriptNameMyTask%"
goto _removeBatchVariablesMyTask
:: ========================================================================
:: MAIN LOGIC
:: ========================================================================
:_runMyTask
REM ===================================================================
REM TODO: Replace this section with your task logic.
REM ===================================================================
if "%_dryRunMyTask%"=="1" (
call :_logMyTask "[DRY RUN] Would process target: %_parOneMyTask%"
goto :eof
)
REM Example: Process files in a target directory.
if NOT "%_checkParOneMyTask%"=="--" (
if NOT EXIST "%_parOneMyTask%" (
call :_logMyTask "ERROR: Target not found: %_parOneMyTask%"
goto :eof
)
call :_logMyTask "Processing target: %_parOneMyTask%"
REM Add task operations here.
) else (
call :_logMyTask "Running default task (no target specified)."
REM Add default task operations here.
)
call :_logMyTask "Task operations complete."
goto :eof
:: ========================================================================
:: SUPPORT FUNCTIONS
:: ========================================================================
:_logMyTask
REM Write a timestamped message to both console and log file.
setlocal EnableDelayedExpansion
for /f "tokens=2 delims==" %%a in ('wmic os get localdatetime /value') do (
set "_dtMyTask=%%a"
)
set "_tsMyTask=!_dtMyTask:~0,4!-!_dtMyTask:~4,2!-!_dtMyTask:~6,2! !_dtMyTask:~8,2!:!_dtMyTask:~10,2!:!_dtMyTask:~12,2!"
echo [!_tsMyTask!] %~1
echo [!_tsMyTask!] %~1 >>"%_logFileMyTask%"
endlocal
goto :eof
:_showHelpMyTask
echo:
for /f "skip=1 tokens=* delims=" %%a in ('findstr /n "^" "%~f0"') do (
set "_line=%%a"
setlocal EnableDelayedExpansion
set "_lineNum=!_line:~0,2!"
if !_lineNum! GTR %_helpLinesMyTask% (
endlocal
goto :eof
)
set "_text=!_line:*:=!"
if defined _text (
echo !_text:~4!
) else (
echo:
)
endlocal
)
goto :eof
:_makeTempDirMyTask
set "_tmpDirMyTask=%TEMP%\%~n0"
if NOT EXIST "%_tmpDirMyTask%" (
mkdir "%_tmpDirMyTask%" >nul 2>nul
)
goto :eof
:: ========================================================================
:: CLEANUP - Remove all batch variables and restore directory.
:: ========================================================================
:_removeBatchVariablesMyTask
set _helpLinesMyTask=
set _dryRunMyTask=
set _logFileMyTask=
set _scriptDirMyTask=
set _scriptNameMyTask=
set _parOneMyTask=
set _checkParOneMyTask=
set _parTwoMyTask=
set _checkParTwoMyTask=
REM Append new variables above this line.
if EXIST "%_tmpDirMyTask%" rmdir /S /Q "%_tmpDirMyTask%" >nul 2>nul
set _tmpDirMyTask=
REM Restore original directory.
if DEFINED _savedDirMyTask (
cd /D "%_savedDirMyTask%"
set _savedDirMyTask=
)
exit /b
Cygwin Reference
Cygwin provides a large collection of GNU and Open Source tools that provide functionality similar to a Linux distribution on Windows, plus a POSIX API DLL (cygwin1.dll) for substantial Linux API compatibility.
Documentation
- Cygwin User's Guide — comprehensive official documentation
- Cygwin FAQ
- Cygwin Homepage
User's Guide — Table of Contents
Chapter 1: Cygwin Overview
- What is it? — POSIX compatibility layer and GNU toolset for Windows
- Quick Start Guide (Windows users) — Getting started for those familiar with Windows
- Quick Start Guide (UNIX users) — Getting started for those familiar with UNIX/Linux
- Are the Cygwin tools free software? — Licensing (GPL/LGPL)
- A brief history of the Cygwin project — Origins and evolution
- Highlights of Cygwin Functionality
- Permissions and Security
- File Access
- Text Mode vs. Binary Mode
- ANSI C Library
- Process Creation
- Signals
- Sockets and Select
- What's new and what changed — Release notes for all versions (1.7.x through 3.6)
Chapter 2: Setting Up Cygwin
- Internet Setup — Installing via
setup-x86_64.exe, mirror selection, package management - Environment Variables — Configuring
PATH,HOME,CYGWINand other environment variables - Changing Cygwin's Maximum Memory — Adjusting memory limits via the registry
- Internationalization — Locale and character set configuration
- Customizing bash —
.bashrc,.bash_profile, and prompt customization
Chapter 3: Using Cygwin
- Mapping path names — How Cygwin maps POSIX paths to Windows paths (
/cygdrive/c=C:\) - Text and Binary modes — Line ending handling (
\nvs\r\n), mount options - File permissions — POSIX permission model on NTFS, ACLs
- Special filenames — Device files,
/proc,/dev, socket files - POSIX accounts, permission, and security — User/group mapping,
passwd/groupfiles,ntsec - Cygserver — Background service for shared memory, message queues, semaphores
- Cygwin Utilities — Built-in command-line tools:
cygcheck— System information and package diagnosticscygpath— Convert between POSIX and Windows pathscygstart— Open files/URLs with associated Windows applicationsdumper— Create Windows minidumpsgetconf— Query POSIX system configurationgetfacl/setfacl— Get/set file access control listsldd— List shared library dependencieslocale— Display locale informationminidumper— Write a minidump of a running processmkgroup/mkpasswd— Generate group/passwd entries from Windows accountsmount/umount— Manage Cygwin mount tablepasswd— Change passwordspldd— List loaded DLLs for a processprofiler— Profile Cygwin programsps— List running processesregtool— Access the Windows registry from the shellsetmetamode— Control meta key behavior in the consolessp— Single-step profilerstrace— Trace system calls and signalstzset— Print POSIX-compatible timezone string- Case-sensitive directories — Enabling per-directory case sensitivity on Windows 10+
- Using Cygwin effectively with Windows — Integration tips, running Windows programs from Cygwin
Chapter 4: Programming with Cygwin
- Using GCC with Cygwin — Compiling C/C++ programs with the Cygwin GCC toolchain
- Debugging Cygwin Programs — Using GDB and other debugging tools
- Building and Using DLLs — Creating shared libraries under Cygwin
- Defining Windows Resources — Resource files and
windres - Profiling Cygwin Programs — Performance profiling with
gprofandssp
Key Concepts for Batch Scripting
Invoking Cygwin from Batch Files
REM Run a Cygwin command from a batch file
C:\cygwin64\bin\bash.exe -l -c "ls -la /home"
REM Convert a Windows path to POSIX for Cygwin
C:\cygwin64\bin\cygpath.exe -u "C:\Users\John Doe\Documents"
REM Convert a POSIX path back to Windows
C:\cygwin64\bin\cygpath.exe -w "/home/jdoe/project"Common Environment Variables
| Variable | Purpose |
|---|---|
CYGWIN | Runtime options (e.g., nodosfilewarning, winsymlinks:nativestrict) |
HOME | User home directory |
PATH | Must include /usr/local/bin:/usr/bin for Cygwin tools |
SHELL | Default shell (typically /bin/bash) |
TERM | Terminal type for console applications |
MSYS2 Reference
MSYS2 provides a collection of tools and libraries for building, installing, and running native Windows software. It uses Pacman (from Arch Linux) for package management.
Getting Started
- Getting Started
- What is MSYS2?
- Who Is Using MSYS2?
- MSYS2 Installer
- News
- FAQ
- Supported Windows Versions and Hardware
- ARM64 Support
Environments
MSYS2 provides multiple environments targeting different use cases:
| Environment | Prefix | Toolchain | C Runtime |
|---|---|---|---|
| MSYS | /usr | GCC | cygwin |
| MINGW64 | /mingw64 | GCC | MSVCRT |
| UCRT64 | /ucrt64 | GCC | UCRT |
| CLANG64 | /clang64 | LLVM | UCRT |
| CLANGARM64 | /clangarm64 | LLVM | UCRT |
Configuration
- Updating MSYS2
- Filesystem Paths
- Symlinks
- Configuration Locations
- Terminals
- IDEs and Text Editors
- Just-in-time Debugging
Package Management
- Package Management
- Package Naming
- Package Index
- Repositories and Mirrors
- Package Mirrors
- Tips and Tricks
- FAQ
- pacman
Development Tools
Package Development
- Creating a new Package
- Updating an existing Package
- Package Guidelines
- License Metadata
- PKGBUILD
- Mirrors
- MSYS2 Keyring
- Python
- Automated Build Process
- Vulnerability Reporting
- Accounts and Ownership
Wiki
Windows Tools and Resources
Updates and News
- Terminal, Command Line and console blog
- Rob van der Woude.com
- Security Bulletins
- OpenCVE
- Old New Thing
- Microsoft Update Catalog
- aka.ms Search
Tools and Utilities
- Windows versions
- RSAT
- Domain Services Tools)
- RSAT Download
- RSAT KBase
- DISM /Add-Capability
- Microsoft Security Compliance Toolkit
- Security Toolkit Release notes (2020)
- Policy Analyzer Release notes
- Microsoft PowerToys
- File Locksmith
- Keyboard Manager
- PowerToys Releases (Github)
- ColorTool.exe
- IE 11 Enterprise Mode Site List Manager
- Local Administrator Password Solution (LAPS)
- LAPS howto
- Sysinternals Suite
- Account Lockout Status
- Account Lockout and Management Tools
- Microsoft Security Compliance Toolkit 1.0
- How to disable SMB 1 (or 2/3 for testing)
- File, Folder and Share Permission Utility Tool
- File Checksum Integrity Verifier
- CERTUTIL
- Policy Analyzer
- Group Policy Management Console SP1
- Object Settings spreadsheet 2003/2008/2008R2/Win7
- Microsoft PowerToys (Github)
- Windows 11 ISO
Tools for Deployment
- Windows 11 Installation Assistant
- Install Windows 11 Without a Microsoft Account
- Windows ADK 23H2
- Windows ADK 24H2
- Windows Server 25
- Microsoft Deployment Toolkit
- Windows Assessment and Deployment Kit
- Rufus USB formatting tool
- Windows 10 Update Assistant 22H2
- Windows 10 ISO
- Windows 10 Pro for Workstations
- Locale Builder 2.0
Package Management
Command-line Utilities
- SysInternals
- bottom — cross-platform graphical process/system monitor
- Caffeine.exe — prevent sleep/lock
- CMDebug — batch file debugger
- Console 2 | review
- ConEmu-Maximus5 | review
- CopyTrans Manager | CopyTrans Filey
- CryptoPrevent
- Cygwin — Part 1 | Part 2 | Part 3
- DOFF | source
- FastCopy
- FindRepl.bat — find and replace in text files
- Gow — GNU on Windows (lightweight Cygwin alternative)
- ImageMagick | scripts
- Jdupes — duplicate file finder
- Joeware.net — AD and Windows tools
- Karen's directory printer
- Microsoft Mouse without Borders
- MParallel — parallel command execution
- Nirsoft Utilities
- NirCMD — command-line automation utility
- NSIS — installer creation
- Npocmaka batch scripts
- zipjs.bat
- PDFtk — PDF manipulation
- Petter Nordahl-Hagen — NT password recovery
- pretentiousname utilities
- Repl.bat — regex replace in text files
- Ritchie Lawrence tools | cmdow
- SetACL — permission management
- SetRes — screen resolution changer
- SoX — audio processing
- Bill Stewart utilities
- System Tools (Somarsoft)
- WebP utilities
Wake-on-LAN
Alternative Terminals
Windows Subsystem for Linux (WSL) Reference
Documentation
- WSL Home
- What is the Windows Subsystem for Linux (WSL)?
- Install WSL
- Install Linux on Windows Server
- Manual install steps
- Best practices for setting up a WSL development environment
- Comparing WSL 1 and WSL 2
- What's new with WSL 2?
- Frequently Asked Questions
- Windows Subsystem for Linux is now open source
Related Tools
Blogs and Community
- Overview post with a collection of videos and blogs
- Command-Line blog
- Windows Subsystem for Linux Blog
- GitHub issue tracker: WSL
- GitHub issue tracker: WSL documentation
Technical Documentation (wsl.dev)
Development
Components
Internals
Architecture
Related skills
FAQ
What does batch-files do?
batch-files skill documents Expert-level Windows batch file (.
When should I use batch-files?
User asks about batch-files, expert-level windows batch file (.bat/.cmd) skill for writing, debugging, and maintaining .
Is this skill safe to install?
Review the Security Audits panel on this page before installing in production.