How to Implement Named (Keyword) Parameters in Batch Script
Standard Batch scripts rely on "Positional Parameters," meaning that the order of arguments matters. If your script expects myscript.bat [Input] [Output], the user cannot swap them without breaking the logic. For more complex scripts, this becomes confusing. "Named Parameters" (also known as Keyword parameters) allow users to specify arguments in any order using flags, such as --input file.txt --output log.csv.
This guide will explain how to build a robust parameter parser in Batch that supports named keywords using a loop and the SHIFT command.
The Logic of Named Parameter Parsing
To handle named parameters, we must:
- Enter a loop that examines the first argument (
%1). - Check if
%1matches a known keyword (e.g.,-i). - If it matches, store the next argument (
%2) into a variable. - Use
SHIFTtwice to discard the keyword and the value, then repeat.
Method: The Processing Loop
This implementation is the industry standard for creating professional-grade CLI tools in Batch.
@echo off
setlocal
:: Set default values
set "InputFile=input.txt"
set "LogFile=log.txt"
set "Verbose=FALSE"
:: Check if any arguments were provided
if "%~1"=="" goto :StartScript
:ParseLoop
:: Check if we have run out of arguments
if "%~1"=="" goto :StartScript
:: Handle --help or -h
if /i "%~1"=="-h" goto :ShowHelp
if /i "%~1"=="--help" goto :ShowHelp
:: Handle --input or -i (requires a value)
if /i "%~1"=="-i" ( call :SetParam InputFile "%~2" || exit /b 1 ) & shift & shift & goto :ParseLoop
if /i "%~1"=="--input" ( call :SetParam InputFile "%~2" || exit /b 1 ) & shift & shift & goto :ParseLoop
:: Handle --log or -l (requires a value)
if /i "%~1"=="-l" ( call :SetParam LogFile "%~2" || exit /b 1 ) & shift & shift & goto :ParseLoop
if /i "%~1"=="--log" ( call :SetParam LogFile "%~2" || exit /b 1 ) & shift & shift & goto :ParseLoop
:: Handle a simple flag (no value needed)
if /i "%~1"=="-v" set "Verbose=TRUE" & shift & goto :ParseLoop
if /i "%~1"=="--verbose" set "Verbose=TRUE" & shift & goto :ParseLoop
:: If an unknown argument is passed
echo [ERROR] Unknown parameter: %~1
echo Use --help to see available options.
exit /b 1
:StartScript
echo --- Configuration ---
echo Input: %InputFile%
echo Log: %LogFile%
echo Debug: %Verbose%
echo ---------------------
:: Validate that required files exist
if not exist "%InputFile%" (
echo.
echo [ERROR] Input file not found: "%InputFile%"
exit /b 1
)
:: (Rest of your script logic here)
echo [OK] Processing %InputFile%...
pause
endlocal
exit /b 0
:: --- Subroutines ---
:SetParam
:: %1 = Variable name, %2 = Value to assign
:: Validates that a value was actually provided
if "%~2"=="" (
echo [ERROR] Parameter -%1 requires a value.
exit /b 1
)
if "%~2:~0,1%"=="-" (
echo [ERROR] Parameter -%1 requires a value, but got another flag: %~2
exit /b 1
)
set "%~1=%~2"
exit /b 0
:ShowHelp
echo.
echo Usage: %~nx0 [OPTIONS]
echo.
echo Options:
echo -i, --input FILE Specify the input file (default: input.txt^)
echo -l, --log FILE Specify the log file (default: log.txt^)
echo -v, --verbose Enable verbose output
echo -h, --help Show this help message
echo.
exit /b 0
Why this works:
if /i: Makes the parameter flags case-insensitive (-Iworks as well as-i).& shift & shift: In one line, we move the pointer twice, once past the "Tag" and once past the "Value."goto :ParseLoop: This restarts the check at the new%1position until the list is empty.:SetParamsubroutine: Validates that a value was actually provided for parameters that require one.
Handling Default Values
One of the best features of named parameters is the ability to have sensible defaults. In our script above, if the user doesn't provide -i, the InputFile variable stays as input.txt. This makes the script easier to use for beginners while still providing power options for advanced users.
Handling Spaces in Values
Because we use %~2 (with the tilde) inside the parser, the script naturally handles quoted strings with spaces.
Example usage: myscript.bat -i "C:\My Data\file.txt"
How to Avoid Common Errors
Wrong Way: Hardcoding %1 and %2 checks
If you try to parse named parameters using if "%1"=="-i" set file=%2, and the user puts the -i in the second position, your script will miss it entirely.
Correct Way: Use the SHIFT loop. It transforms positional parameters into a stream that can be audited from start to finish regardless of order.
Problem: Missing values after a flag
If the user types myscript.bat -i -l output.log, the parser would assign -l as the input file because it blindly takes %2 as the value.
Best Practice: Validate that the value following a flag is not itself another flag (as shown in the :SetParam subroutine).
Problem: Infinite Loops
If you forget the shift command inside your ParseLoop, the script will look at the same -i forever, leading to an infinite loop that freezes the command prompt.
Best Practice: Ensure every if block that identifies a parameter finishes with at least one shift.
Best Practices and Rules
1. Unified Interface
Consistency is key. If you use -i for input, always use -o for output. Follow common command-line conventions (like those in Linux or Git) so your users find your Batch tool intuitive.
2. Help Command
Always include a -h or --help parameter that shows usage instructions (as implemented in the script above).
3. Argument Validation
After the loop finishes, validate the resulting variables. For example, check that the input file actually exists before attempting to process it (as shown in the :StartScript section).
Conclusions
Implementing named parameters in Batch script elevates your code from a simple automation snippet to a professional CLI utility. By allowing users to specify exactly what they want without worrying about argument order, you reduce errors and improve the "User Experience" of the command line. This parsing logic is a foundational pattern for any advanced Windows automation project.