Skip to main content

How to Create an Array of Variables in Batch Script

In most programming languages, an array is a fundamental data structure for storing a list of items. While the Windows Batch language does not have a true, native array type, you can effectively simulate or emulate array-like behavior. This is crucial for processing lists of items like servers, filenames, or user inputs.

This guide will teach you the standard method for creating "pseudo-arrays" using indexed environment variables. You will learn how to define, access, and iterate through these arrays, a powerful technique for handling collections of data. We will also briefly cover the modern PowerShell alternative, which uses real arrays.

The Challenge: No Native Arrays in Batch

The primary difficulty is that you cannot define an array with a simple command like SET MyArray = ("apple", "banana", "cherry"). The cmd.exe interpreter does not understand this syntax. Instead, we simulate an array by creating a series of standard variables that follow a consistent naming pattern.

The Core Method: Pseudo-Arrays (Indexed Variables)

The most common and flexible method is to create a set of variables with a common prefix and a numeric index, usually enclosed in brackets.

Example of syntax:

SET "MyArray[0]=First Item"
SET "MyArray[1]=Second Item"
SET "MyArray[2]=Third Item"

Here, MyArray is not a single variable, but a family of variables (MyArray[0], MyArray[1], etc.) that we agree to treat as an array. The number is the "index," which is conventionally zero-based (starts at 0).

To access an element, you must use Delayed Expansion. ECHO !MyArray[1]!

The Modern Alternative: Using PowerShell

For context, it's important to see how a real array works. PowerShell has native support for arrays, and its syntax is much cleaner and more powerful.

PowerShell Syntax: powershell -Command "$myArray = @('First Item', 'Second Item'); $myArray[1]"

This single command defines the array and accesses the second element. While you can't manage PowerShell arrays directly in batch, this demonstrates the goal we are trying to emulate.

Basic Example: Creating and Accessing an Array

This script defines a pseudo-array of server names and then accesses a specific element.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

ECHO Defining the server array...

REM --- Define the array elements ---
SET "servers[0]=web-prod-01"
SET "servers[1]=db-prod-01"
SET "servers[2]=api-prod-01"
SET "ServerCount=3"

ECHO.
ECHO Accessing a specific element...
ECHO The second server in the list is: !servers[1]!
ENDLOCAL

Output:

Defining the server array...

Accessing a specific element...
The second server in the list is: db-prod-01

How to Iterate Through a Pseudo-Array

The real power of an array is the ability to loop through its elements. This is done using a FOR /L loop that counts from the starting index to the last.

Script

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

SET "servers[0]=web-prod-01"
SET "servers[1]=db-prod-01"
SET "servers[2]=api-prod-01"
SET "ServerCount=3"

REM --- Calculate the last index (Count - 1) ---
SET /A "LastIndex = %ServerCount% - 1"

ECHO.
ECHO --- Looping through all servers ---
FOR /L %%i IN (0,1,%LastIndex%) DO (
ECHO Processing server #%%i: !servers[%%i]!
)
ENDLOCAL
  • FOR /L %%i IN (0,1,%LastIndex%): This loop creates a counter, %%i, that goes from 0 to LastIndex one step at a time.
  • !servers[%%i]!: This is the key. Inside the loop, %%i will be 0, then 1, then 2. Delayed expansion allows us to use this changing number to access !servers[0]!, then !servers[1]!, and so on.

Common Pitfalls and How to Solve Them

Problem: Accessing Elements Inside a Loop (Delayed Expansion)

This is the most critical pitfall. If you do not enable delayed expansion and use ! instead of %, your script will fail.

An example of script with error:

REM This will FAIL.
FOR /L %%i IN (0,1,2) DO (
ECHO %servers[%%i]%
)

This fails because %servers[%%i]% is parsed only once before the loop starts, when %%i has no value.

Solution: Always Use SETLOCAL ENABLEDELAYEDEXPANSION

This must be at the start of your script or subroutine. It allows you to use the ! syntax, which correctly evaluates the variable's value on each iteration of the loop.

Problem: Getting the Length of the Array

Batch has no built-in way to get the size of a pseudo-array. You cannot ask, "How many elements are in MyArray?"

Solution: Maintain a Counter Variable

The best practice is to maintain a separate variable that holds the count of the elements. You must update this counter every time you add an element to the array.

SET "ItemCount=0"

SET "MyArray[%ItemCount%]=First"
SET /A "ItemCount+=1"

SET "MyArray[%ItemCount%]=Second"
SET /A "ItemCount+=1"

ECHO The array has %ItemCount% elements.

Practical Example: A Script to Ping a List of Servers

This script defines a list of critical servers in a pseudo-array and then loops through them, pinging each one to check its status.

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION

REM --- Define the list of servers to check ---
SET "servers[0]=google.com"
SET "servers[1]=localhost"
SET "servers[2]=a-fake-server-name"
SET "ServerCount=3"

REM --- Loop through the array ---
SET /A "LastIndex = %ServerCount% - 1"
FOR /L %%i IN (0,1,%LastIndex%) DO (
ECHO.
ECHO ----------------------------------
ECHO Pinging server: !servers[%%i]!
ECHO ----------------------------------
PING -n 2 !servers[%%i]!
)

ENDLOCAL

Conclusion

While batch script does not have true arrays, the pseudo-array technique using indexed variables is a powerful and flexible substitute for handling lists of data.

To use them successfully:

  • Define elements using a consistent pattern: SET "MyArray[0]=Value".
  • Always use SETLOCAL ENABLEDELAYEDEXPANSION to be able to access elements inside loops.
  • Access elements dynamically using a counter variable: !MyArray[%%i]!.
  • Keep a separate counter variable to track the size of your array.

For simple lists, this method is very effective. For more complex data manipulation involving sorting, filtering, or resizing lists, using a PowerShell one-liner is the more robust and modern solution.