Published in Articles on by Michiel van Oosterhout ~ 6 min read
As we've seen in the Windows command-line interface, part 1, all command-line programs on Windows are connected to Console Window Host. Even the new Windows Terminal app connects to a pseudo console that is provided by Console Window Host. Command-line programs can specify the forground and background color of their output via the Windows Console API or via terminal sequences. This article looks briefly at the history of color in Console Window Host and how the colors can be changed without changing the command-line programs themselves.

Color in the Windows Console API
The Windows Console API historically has allowed command-line programs to specify color by combining the following attribute flags defined in WinCon.h
:
FOREGROUND_BLUE 0x0001
FOREGROUND_GREEN 0x0002
FOREGROUND_RED 0x0004
FOREGROUND_INTENSITY 0x0008
BACKGROUND_BLUE 0x0010
BACKGROUND_GREEN 0x0020
BACKGROUND_RED 0x0040
BACKGROUND_INTENSITY 0x0080
Effectively this provides 3 bits to specify a color and an additional bit to adjust that color (more 'intense', or 'brighter'). Perhaps in the initial version of Windows NT the 4-bit value was interpreted literally by Console Window Host, but later versions of Console Window Host, as well as the Windows Terminal app, interpret the value as an entry in a lookup table, and allow you to configure the actual color value for each entry.
The console color palette
The color palette used by Console Window Host is a lookup table with 16 numbered entries (#0
through #A
, using base-16) each of which is associated with a 24-bit RGB color value. Although you are free to set any color value for each entry, the entries have predefined names based on the color you would get if you would interpret the attribute flags from WinCon.h
literally:
0 = Black 8 = Gray
1 = Blue 9 = Light Blue
2 = Green A = Light Green
3 = Aqua B = Light Aqua
4 = Red C = Light Red
5 = Purple D = Light Purple
6 = Yellow E = Light Yellow
7 = White F = Bright White
Part of the help text for Windows Command Processor's built-in color
command.
There are some notable differences to be aware of though.
.NET's System.ConsoleColor
enumeration used by PowerShell has different names. ECMA-48's SGR terminal sequences to set the foreground and background color using a 3- or 4-bit color palette use different names as well, and also swap the (Light) Blue and (Light) Red, and the (Light) Aqua and (Light) Yellow entries.
The following table shows the differences for each entry in the color palette:
Entry | Name | .NET | ECMA-48 | R | G | B | Color |
---|---|---|---|---|---|---|---|
#0 |
Black | Black | ^[[30m Black |
12 |
12 |
12 |
|
#1 |
Blue | DarkBlue | ^[[34m Blue |
0 |
55 |
218 |
|
#2 |
Green | DarkGreen | ^[[32m Green |
19 |
161 |
14 |
|
#3 |
Aqua | DarkCyan | ^[[36m Cyan |
58 |
150 |
221 |
|
#4 |
Red | DarkRed | ^[[31m Red |
197 |
15 |
31 |
|
#5 |
Purple | DarkMagenta | ^[[35m Magenta |
136 |
23 |
152 |
|
#6 |
Yellow | DarkYellow | ^[[33m Yellow |
193 |
156 |
0 |
|
#7 |
White | Gray | ^[[37m White |
204 |
204 |
204 |
|
#8 |
Gray | DarkGray | ^[[90m Bright Black |
118 |
118 |
118 |
|
#9 |
Light Blue | Blue | ^[[94m Bright Blue |
59 |
120 |
255 |
|
#A |
Light Green | Green | ^[[92m Bright Green |
22 |
198 |
12 |
|
#B |
Light Aqua | Cyan | ^[[96m Bright Cyan |
97 |
214 |
214 |
|
#C |
Light Red | Red | ^[[91m Bright Red |
231 |
72 |
86 |
|
#D |
Light Purple | Magenta | ^[[95m Bright Magenta |
180 |
0 |
158 |
|
#E |
Light Yellow | Yellow | ^[[93m Bright Yellow |
249 |
241 |
165 |
|
#F |
Bright White | White | ^[[97m Bright White |
242 |
242 |
242 |
(The terminal sequences shown here set the foreground color. To set the background color use ^[[40m
through ^[[47m
and ^[[100m
through ^[[107m
instead.)
Any particular combination of color values is called a color scheme or color theme 1, and the default color scheme (known as Campbell) has the color values shown in the table above.
The console screen buffer
The output of command-line programs is mapped onto a screen buffer, a 2-dimensional grid of cells. For each cell the screen buffer stores a record 2 containing the ASCII or Unicode character that should be rendered, along with the text attributes that should be applied to that character when it is rendered.
The screen buffer sets the text attributes of a cell to the current text attributes everytime that cell's character is set:
The current text attributes of [the] screen buffer are used for characters subsequently written or echoed by the high-level functions. Console Screen Buffers
Before writing text a command-line program can change the screen buffer's current text attributes using the Windows Console API's SetConsoleTextAttribute
function, or using a terminal sequence.

The terminal sequence ^[[0m
can be used to reset the text attributes to the defaults. To reset the text attributes using the Windows Console API, use GetConsoleScreenBufferInfo
to get the current text attributes before changing them, and use the returned value to change them back after writing the text.
Default text attributes
When the screen buffer is first created its current text attributes are set to use #0
(Black) for the background color and #7
(White) for the foreground color (these are the defaults stored in the Window Registry). The color values for those entries are listed in the table above. Every cell's character is then set to space
, ensuring every cell has text attributes. Then the cursor is positioned at the 0,0
coordinate and the command-line program is started.

Windows PowerShell, when started directly, is configured to use different color entries. When the screen buffer is first created its current text attributes are set to use #5
(Purple) for the background color and #6
(Yellow) for the foreground color. The color values for those entries are set to a blue and a very light gray respectively.

This particular configuration may have caused some confusion, as it sets color values that are incongruent with the color palette entry's predefined names.
The color
command
Windows Command Processor has a built-in color
command that can be used to set the text attributes of every cell in the screen buffer. Without arguments it will reset the default text attributes. With the attr
argument it will set the text attributes specified. For example color 1B
will set the background color to #1
(Blue) and the foreground color to #B
(Light Aqua).

color
command to set the text atrributes for every cell of the screen buffer
To use the color
command in Windows PowerShell you can run cmd /c color 1B
. This starts the Windows Command Processor, which then changes the screen buffer and exits back to Windows PowerShell. The changes to the screen buffer persist because the screen buffer is independent of the command-line program.
Summary
Colors in Console Window Host have historically been based on a 4-bit color palette. Although the palette only has 16 entries, each entry can be set to any 24-bit color value, and many color themes are available. Color changes via the Windows Console API or via terminal sequences change the screen buffer's current text attributes, and only apply to text written after the change.
-
For a list of color themes see windowsterminalthemes.dev or iterm2colorschemes.com. ↩︎
-
See CHAR_INFO structure. ↩︎