Published in Articles on by Michiel van Oosterhout ~ 3 min read
Using the color function we built for Bash as inspiration, let's try to achieve something similar for Windows Command Processor. We will use the Commando extension system to create a Color extension that will help us create colored output.
The Color extension for Windows Command Processor
Windows Command Processor already has a color
command, used to change the background and foreground colors of the entire buffer. But we want something similar to the color
function we created for Bash earlier, which only outputs the SGR terminal sequence to change the color of the output that follows it.
# Ensure the directory exists
$path = "$Env:LOCALAPPDATA\Commando\Color"
$_ = New-Item $path -Force -ItemType Directory
# Declare the ESC control code
$esc = [char]0x1B
# Declare the script contents
$script = @"
@echo off
setlocal enabledelayedexpansion
rem Normal colors
set colors_normal[k]=0
set colors_normal[r]=1
set colors_normal[g]=2
set colors_normal[y]=3
set colors_normal[b]=4
set colors_normal[m]=5
set colors_normal[c]=6
set colors_normal[w]=7
rem Bright colors
set colors_bright[K]=60
set colors_bright[R]=61
set colors_bright[G]=62
set colors_bright[Y]=63
set colors_bright[B]=64
set colors_bright[M]=65
set colors_bright[C]=66
set colors_bright[W]=67
rem Default background color
set colors_normal[0]=9
rem Start the SGR terminal sequence
set seq=$esc[
rem Parse background color
set bg=%1
set bg=%bg:~0,1%
if "%bg%" == "-" (
rem Parameters for RGB color
set seq=%seq%48;2;%TERM_BACKGROUND_COLOR%
) else if "%bg%" == "+" (
rem Parameters for RGB color
set seq=%seq%48;2;%TERM_FOREGROUND_COLOR%
) else (
rem Parameter for palette-based background color
echo %bg% | findstr [KRGYBMCW] 1>NUL
if errorlevel 1 (
set bg=!colors_normal[%bg%]!
) else (
set bg=!colors_bright[%bg%]!
)
set /a bg=!bg! + 40
set seq=%seq%!bg!
)
rem Separate the parameters for background color and foreground color
set seq=%seq%;
rem Parse foreground color
set fg=%1
set fg=%fg:~1,1%
if "%fg%" == "-" (
rem Parameters for RGB color
set seq=%seq%38;2;%TERM_BACKGROUND_COLOR%
) else if "%fg%" == "+" (
rem Parameters for RGB color
set seq=%seq%38;2;%TERM_FOREGROUND_COLOR%
) else (
rem Parameter for palette-based background color
echo %fg% | findstr [KRGYBMCW] 1>NUL
if errorlevel 1 (
set fg=!colors_normal[%fg%]!
) else (
set fg=!colors_bright[%fg%]!
)
set /a fg=!fg! + 30
set seq=%seq%!fg!
)
rem Finish the SGR terminal sequence
set seq=%seq%m
rem Output the SGR terminal sequence
<NUL set /p _=%seq%
endlocal
"@
# Create the Windows Command Processor script
$path = "$path\color.cmd"
Set-Content -Path $path -Value $script
The lack of true arrays and the case-insensitivity of variable names makes the Windows Command Processor version slightly longer and more complex than the Bash version. Also notice how we output the terminal sequence without a new line by using set /p
to prompt for input, and redirecting from NUL
to immediately provide the input.
Now we can call the function, e.g. call %CMD%\Color\color.cmd rw
to set the background color to red and the foreground color to white.

Conclusion
Although not as easy to write (or read), the Windows Command Prompt scripting language can be used to create a function that renders terminal sequences for colored output.