How to Create Colored Output Using ANSI Escape Codes in Batch Script
For decades, Batch scripts were limited to standard white-on-black text or a single global color change using the color command. However, modern Windows 10 and 11 terminals (Windows Terminal and the updated ConHost) now support ANSI Escape Codes. This allows you to print vibrant, multi-colored text and status messages without using external tools or complex "PowerShell hacks."
In this guide, we will demonstrate how to enable and use ANSI colors to make your Batch scripts more professional and user-friendly.
Enabling ANSI Support
On modern Windows versions (Windows 10 1511+), ANSI support is often enabled by default in Windows Terminal. However, the legacy console host (conhost.exe) may need Virtual Terminal Processing enabled explicitly. Adding a registry tweak at the top of your script ensures colors work regardless of which console is being used.
The Professional Header
Add this to the top of your script to guarantee colors work:
@echo off
:: Enable Virtual Terminal Processing for ANSI escape code support
:: This sets the registry value for the current user's console.
:: A new console session may be needed for the change to take effect.
reg query HKCU\Console /v VirtualTerminalLevel >nul 2>&1
if %ERRORLEVEL% NEQ 0 (
reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1 /f >nul 2>&1
echo [NOTE] ANSI support has been enabled. Please restart your terminal if colors do not appear.
)
Basic ANSI Color Codes
ANSI codes start with an "Escape Character." In Batch, the escape character is represented as ESC (ASCII 27). We define these as variables to make the script readable.
| Color | Standard Sequence | Bright Sequence |
|---|---|---|
| Reset | ESC[0m | N/A |
| Red | ESC[31m | ESC[91m |
| Green | ESC[32m | ESC[92m |
| Yellow | ESC[33m | ESC[93m |
| Blue | ESC[34m | ESC[94m |
Creating a Color Utility Script
The following example shows how to set up color variables and print status messages in Red, Green, and Yellow.
@echo off
setlocal enabledelayedexpansion
:: Define the Escape character (ASCII 27)
for /F "delims=" %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
:: Verify that the escape character was captured
if not defined ESC (
echo [WARNING] Could not generate ANSI escape character. Colors will not work.
echo Continuing without color support...
set "C_RESET="
set "C_RED="
set "C_GREEN="
set "C_YELLOW="
set "C_BLUE="
goto :start
)
:: Define color codes
set "C_RESET=!ESC![0m"
set "C_RED=!ESC![91m"
set "C_GREEN=!ESC![92m"
set "C_YELLOW=!ESC![93m"
set "C_BLUE=!ESC![94m"
:start
:: Examples of output
echo !C_BLUE![INFO]!C_RESET! Initializing script...
echo !C_YELLOW![WAIT]!C_RESET! Downloading assets...
echo !C_GREEN![SUCCESS]!C_RESET! All tasks completed perfectly.
echo !C_RED![ERROR]!C_RESET! Connection failed. Check your internet.
endlocal
pause
Breakdown of the variable setup:
- The
ESCvariable: We use aprompt $Etrick to capture the literal Escape character (ASCII 27) into a variable. You cannot simply type this character in a text editor, it is a non-printable control character. - Delayed expansion: Because the ESC character and the square bracket
[are parsed during variable expansion, we useenabledelayedexpansionand!var!syntax to avoid premature parsing issues in certain contexts. - The
C_RESETvariable: This is the most important code. It tells the terminal to stop using the previous color and return to the default. If you forget this, the rest of your terminal session will stay that color!
Advanced Colors: Backgrounds and Formatting
You can also use ANSI to change the background color or apply formatting like underlines.
- Underline:
ESC[4m - Reverse Video (Highlight):
ESC[7m - Green Background:
ESC[42m
echo !ESC![4;32mThis is Underlined Green Text!C_RESET!
echo !ESC![7;91mCRITICAL ALERT: REVERSE RED!C_RESET!
Note: Combined codes are separated by semicolons inside a single escape sequence. For example, ESC[4;32m applies both underline (4) and green foreground (32) at once.
Comparisons: color command vs. ANSI Codes
colorcommand: Changes the background and foreground of the entire window simultaneously. Good for simple themes but cannot style individual lines or words.- ANSI Codes: Allows line-by-line, word-by-word color control. Essential for modern, interactive CLI tools.
Best Practices
- Always define a Reset: End every colored line with your
!C_RESET!variable so subsequent output returns to default colors. - Color for Meaning: Use standard conventions (Green=Success, Red=Error, Yellow=Warning). Don't use color just for the sake of it, as it can make the screen hard to read.
- Graceful Degradation: If you are writing a script for older systems (like Windows 7), check whether the ESC variable was successfully defined before using color codes. Otherwise, users will see garbled characters like
←[91mon their screen. The fallback in the script above handles this by setting all color variables to empty strings.
Conclusion
ANSI escape codes breathe new life into "boring" Batch scripts. By defining a simple set of color variables at the beginning of your project, you can dramatically improve the user experience of your scripts, making errors jump out and successes feel rewarding. In the world of modern Windows Dev-Ops, a colorful, readable log is a professional log.