How-to: Create Batch file macros

A macro allows you to embed blocks of code in a variable. Like calling a subroutine or function this allows reusing the same block of code multiple times, the difference is that by placing the code in a variable the performance will be much faster.

This is an advanced technique but can be very useful in scripts that include large blocks of code or looping commands where the performance of other methods is too slow.

A macro which runs exit /b

set _ex=exit /b

You can then exit a subroutine with:


A macro which lists all the .XLS files in a folder:

Set _macro=Dir c:\demo\*.xls

We can now run the Macro like this:


A macro to allow comments within bracketed code blocks [source]:

Set "[=rem/||(" & set "]=)"

For %%G in (first second) do (
    Echo first not commented line of the %%G execution
        this is a multi line
    Echo second not commented line of the %%G execution

So far so like the DOSKEY command, but to make this more powerful you will want to pass arguments to the macro, in the example above you might want to pass the name of the folder to be listed.

Passing arguments to a macro is not particularly easy, the best method (discovered by Jeb) is to place a For /L command within the macro, set to run 2 steps each time the macro is run:

The basic structure of the macro definition:

Set _macro=For /l %%n in (1 1 2) do if %%n==2 (Echo Main MACRO goes here.) else setlocal enableDelayedExpansion ^& Set argv=, 

%_macro% arg1 arg2

 :: The macro will expand to:
 :: for /l %%n in (1 1 2) do if %%n==2 (Echo Main MACRO goes here.) else setlocal enableDelayedExpansion & Set argv=, arg1 arg2

 :: which is equivalent to:
 ::    setlocal enableDelayedExpansion
 ::    Set argv= arg1 arg2
 ::    Echo Main MACRO goes here.


@echo off
setlocal DisableDelayedExpansion
set LF=^

::Above 2 blank lines are required - do not remove
set ^"\n=^^^%LF%%LF%^%LF%%LF%^^"

set _macrodemo=for /L %%n in (1 1 2) do if %%n==2 (%\n%
      for /F "tokens=1 delims=, " %%G in ("!argv!") do (%\n%
         echo _argument1=%%G %\n%
         set "_argument1=!%%~G!"%\n%
         dir !_argument1!\*.xls%\n%
      ) %\n%
) ELSE setlocal enableDelayedExpansion ^& set argv=,

set "_testfolder=c:\demo"
%_macrodemo% _testfolder

In a macro where more than one argument need to be passed, these will become tokens 2,3,4... in the FOR / F command.

A library of macros can be defined by running a single MACROS.CMD batch file, allowing the library macros to be used in multiple batch files.

Credits: Ed Dyreen, Jeb and Dave Benham, the original dostips forum threads are here (basic concepts) and here (macros with parameters).

“Macro dictionary definition: 1. Large 2. Long 3. Inclusive” ~ from the Greek 'makros'

Related commands

How-to: functions - How to package blocks of code.
CALL - Call one batch program/subroutine from another.
How the %LF% newline variable hack works - StackOverflow.
DOSKEY - Edit command line, recall commands, and create macros.

Copyright © 1999-2023
Some rights reserved