Skip to main content

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.

ColorStandard SequenceBright Sequence
ResetESC[0mN/A
RedESC[31mESC[91m
GreenESC[32mESC[92m
YellowESC[33mESC[93m
BlueESC[34mESC[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:

  1. The ESC variable: We use a prompt $E trick 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.
  2. Delayed expansion: Because the ESC character and the square bracket [ are parsed during variable expansion, we use enabledelayedexpansion and !var! syntax to avoid premature parsing issues in certain contexts.
  3. The C_RESET variable: 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!
info

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

  • color command: 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

  1. Always define a Reset: End every colored line with your !C_RESET! variable so subsequent output returns to default colors.
  2. 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.
  3. 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 ←[91m on 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.