cheat sheet

cls

Clear all text from the cmd.exe or PowerShell console window and reset the cursor to the top-left — the single command for resetting a terminal session's visible output.

cls — Clear Console Screen

What it is

cls (Clear Screen) is a built-in Windows command that erases all text currently visible in the console window and moves the cursor to the top-left corner — equivalent to the Unix clear command. Use it at the top of interactive batch menus, after long command output, or anywhere you want a clean terminal view. In PowerShell, Clear-Host (alias cls) does the same thing.

Availability

cls is an internal cmd.exe command present on every Windows version, not a standalone .exe. It also works as an alias in PowerShell via Clear-Host.

cmd
help cls

Output:

objectivec
Clears the screen.

CLS

Syntax

cls takes no arguments.

cmd
cls

Output: (screen cleared — cursor moves to top-left)

Clearing the screen in a batch script

Batch menus and interactive scripts often call cls before displaying a menu so previous output doesn't clutter the view.

cmd
@echo off
:menu
cls
echo ==================
echo   Maintenance Menu
echo ==================
echo  1. Backup files
echo  2. Clean temp
echo  3. Exit
echo ==================
set /P choice=Choose: 
if "%choice%"=="1" goto backup
if "%choice%"=="2" goto clean
if "%choice%"=="3" exit /b
goto menu

Output:

markdown
==================
  Maintenance Menu
==================
 1. Backup files
 2. Clean temp
 3. Exit
==================
Choose:

Clearing after a long-running command

Calling cls after verbose output from a build tool or installer leaves a clean terminal for subsequent commands.

cmd
@echo off
echo Running installer...
msiexec /quiet /i myapp.msi
cls
echo Installation complete.

Output:

code
Installation complete.

Suppressing cls output in scripts

cls itself produces no stdout; it writes directly to the console buffer. Redirecting it to NUL is a no-op but harmless — it does not suppress the screen-clear effect.

cmd
cls > NUL
echo Screen cleared.

Output:

code
Screen cleared.

cls in PowerShell

In PowerShell, cls is an alias for Clear-Host. Both clear the screen identically; Clear-Host is the preferred explicit form in scripts.

powershell
cls

Output: (screen cleared)

powershell
Clear-Host

Output: (screen cleared)

Common pitfalls

  1. cls clears only the visible buffer, not scroll-back history — the console's scroll-back buffer is cleared as well, so prior output is unrecoverable from the window; pipe important output to a file before calling cls.
  2. cls inside a pipe is a no-opecho text | cls does not make sense; cls ignores stdin and writes directly to the console.
  3. Redirecting cls to a file creates an empty filecls > screen.txt creates an empty file; the escape sequences go to the console handle, not stdout.
  4. Does not work in non-interactive contexts — when cmd.exe is spawned without a console (e.g. via CreateProcess with DETACHED_PROCESS), cls may fail silently.

Real-world recipes

Interactive loop with periodic clear

cmd
@echo off
:loop
cls
echo Current time: %TIME%
echo Press Ctrl+C to exit, any key to refresh.
pause > NUL
goto loop

Output:

vbnet
Current time: 14:22:05.34
Press Ctrl+C to exit, any key to refresh.

Clear screen at the start of a deployment script

cmd
@echo off
cls
echo ===================================
echo  Deploy: MyApp v2.1.0
echo  Host:   myhost
echo  Date:   %DATE%
echo ===================================
echo.

Output:

markdown
===================================
 Deploy: MyApp v2.1.0
 Host:   myhost
 Date:   Mon 04/28/2026
===================================

How cls actually clears the screen

cls is not a separate executable on Windows — it is an internal command implemented inside cmd.exe. When you type cls, the shell calls the Win32 console APIs (GetConsoleScreenBufferInfo, FillConsoleOutputCharacter, FillConsoleOutputAttribute, SetConsoleCursorPosition) to overwrite every cell in the visible window with spaces, reset the attributes to the current default colour, and move the cursor home. There is no escape sequence being emitted to stdout — the call is direct against the console handle. This matters because it explains why redirecting cls is a no-op: the action happens through a side-channel that > and | cannot capture.

cmd
rem Demonstrates that cls writes nothing to stdout
cls > saved.txt
dir saved.txt

Output:

swift
03/24/2026  10:14 AM                 0 saved.txt

The file is zero bytes — the screen was cleared but nothing reached the redirected handle.

ANSI escape sequences as a portable alternative

Modern Windows 10 (1607+) and Windows 11 consoles understand the same VT100/ANSI escape sequences as Linux and macOS terminals. Emitting ESC[2J clears the screen and ESC[H (or ESC[0;0H) homes the cursor — together they are the portable cross-platform equivalent of cls. The escape byte is 0x1B (decimal 27). In a batch script you can produce it with prompt $E trick or by embedding the literal byte in a here-doc with forfiles, but PowerShell and modern shells let you write it directly.

powershell
# PowerShell — write the ANSI clear sequence directly
$esc = [char]27
Write-Host "$esc[2J$esc[H" -NoNewline

Output: (screen cleared the same as cls)

powershell
# PowerShell 6+ accepts `e for the escape byte
Write-Host "`e[2J`e[H" -NoNewline

Output: (screen cleared)

For mixed scripts that may run in older shells, Clear-Host remains the safe path. ANSI sequences fail silently on legacy conhost.exe builds prior to Windows 10 1607, printing literal ←[2J characters instead of clearing.

VT100 sequences cheat sheet

The same byte stream that clears the screen can also scroll, colour, and reposition the cursor. These are useful when writing TUIs, progress meters, or animations directly from cmd.exe or PowerShell without a library.

SequenceEffect
ESC[2JErase entire screen (cursor stays put)
ESC[3JErase entire screen and scroll-back buffer (Windows 10 1809+)
ESC[HCursor to row 1, column 1
ESC[0;0HSame as above, explicit row/column
ESC[KErase from cursor to end of line
ESC[1KErase from start of line to cursor
ESC[2KErase the entire current line
ESC[<n>AMove cursor up n rows
ESC[<n>BMove cursor down n rows
ESC[<n>CMove cursor right n columns
ESC[<n>DMove cursor left n columns
ESC[sSave cursor position
ESC[uRestore saved position
ESC[?1049hSwitch to alternate screen buffer (vim-style)
ESC[?1049lSwitch back to main buffer
powershell
# Full scroll-back clear — equivalent to Windows Terminal Ctrl+Shift+K
Write-Host "`e[2J`e[3J`e[H" -NoNewline

Output: (screen and scroll-back history cleared)

Clearing the scroll-back buffer

By default, cls only blanks the visible viewport; lines that scrolled off the top remain in the scroll-back buffer and can be retrieved with the mouse wheel. On Windows 10 1809 and later the ESC[3J sequence wipes the scroll-back as well, matching what clear does on Linux when called with -x or what Windows Terminal does on Ctrl+Shift+K.

powershell
function Clear-AllBuffers {
    Write-Host "`e[2J`e[3J`e[H" -NoNewline
}
Clear-AllBuffers

Output: (visible window and scroll-back history both gone)

In legacy conhost.exe and Windows Terminal you can also clear the scroll-back via the right-click menu (Properties → Layout lets you shrink the buffer to zero rows, although that has side effects). For pure cmd.exe without VT support, the only true scroll-back wipe is closing and reopening the console.

cls vs clear — cross-platform comparison

cls is the Windows internal; clear is the POSIX equivalent shipped on Linux, macOS, BSD, and inside WSL distributions. The two cannot be used interchangeably without aliasing — clear on cmd.exe reports "is not recognised as an internal or external command" and cls in a Bash shell produces a similar error. PowerShell normalises both: cls and clear are both aliases of Clear-Host.

ShellCommandImplementation
cmd.execlsInternal — Win32 console API
PowerShell 5.1Clear-Host (cls, clear)Function calling Win32 console API
PowerShell 7 (Windows)Clear-Host (cls, clear)Emits ESC[2J ESC[3J ESC[H
PowerShell 7 (Linux/macOS)Clear-Host (cls, clear)Shells out to clear
Bash / Zsh / FishclearReads clear capability from terminfo
WSLclearSame as Bash — uses terminfo
Windows Terminal (any shell)Built-in: Ctrl+L / Ctrl+Shift+KRenderer API call
bash
# Linux / WSL — clear uses terminfo
clear              # equivalent of cls
clear -x           # clear visible but keep scroll-back (Linux only)
tput clear         # raw terminfo capability
printf '\e[2J\e[H' # raw ANSI — portable everywhere modern

Output: (screen cleared)

Keyboard shortcut equivalents

You rarely need to type cls at an interactive prompt — every modern Windows terminal has a keyboard shortcut that does the same thing. Knowing these saves four keystrokes hundreds of times a day.

ShortcutWhere it worksWhat it does
Ctrl+LPowerShell 5.1+ (PSReadLine), bash, zsh, fish, Windows TerminalClears visible viewport, keeps scroll-back
Ctrl+Shift+KWindows Terminal (all profiles)Clears the entire buffer (visible + scroll-back)
Cmd+KiTerm2, Apple TerminalClears scroll-back too
Right-click → Clear BufferWindows Terminal title bar menuSame as Ctrl+Shift+K
cls / clearcmd / PowerShell / bashVisible viewport only (Windows)

Ctrl+L in PowerShell only works when the PSReadLine module is loaded — that is the default in PowerShell 5.1+ and 7+. Inside a cmd.exe window, Ctrl+L does nothing; you must type cls.

Windows Terminal vs conhost behaviour

Windows ships two console hosts. conhost.exe is the legacy host used when you launch cmd.exe directly from Win+R. Windows Terminal (wt.exe) is the modern tabbed host installed by default on Windows 11 and via the Store on Windows 10. They differ in how they handle clear operations.

Featureconhost.exeWindows Terminal
cls behaviourClears visible viewportClears visible viewport
ESC[2J supportYes (Windows 10 1607+)Yes
ESC[3J (scroll-back wipe)Windows 10 1809+Yes
Scroll-back retained after clsYes (mouse wheel up)Yes
Alternate screen bufferLimitedFull
Keyboard Ctrl+LNoYes (in PSReadLine shells)
Ctrl+Shift+KNoYes (clears all)
RendererGDIDirectWrite (GPU)

If a script needs to reset everything including scroll-back regardless of which host the user is on, write both cls and the ESC[3J sequence — conhost ignores ESC[3J on builds older than 1809 but does no harm.

cls in PowerShell — Clear-Host in depth

Clear-Host is an advanced PowerShell function (not a cmdlet) built into the engine. Inspecting its definition shows it as a thin wrapper that uses platform-specific logic.

powershell
Get-Command Clear-Host | Format-List *

Output:

yaml
CommandType        : Function
Name               : Clear-Host
Definition         : ...uses [Console]::Clear() on Windows...
Module             :
...
powershell
# Inspect the function body
(Get-Command Clear-Host).ScriptBlock

Output:

ini
$RawUI = $Host.UI.RawUI
$RawUI.CursorPosition = @{X=0;Y=0}
$RawUI.SetBufferContents(
    @{Top = -1; Bottom = -1; Right = -1; Left = -1},
    @{Character=' '; ForegroundColor=$rawui.ForegroundColor; BackgroundColor=$rawui.BackgroundColor}
)

PowerShell calls into the host's RawUI and resets the entire buffer to space characters with current colours. On non-Windows PowerShell (Linux/macOS) the engine substitutes a call to the system clear binary instead.

powershell
# All three forms are identical
cls
clear
Clear-Host

Output: (screen cleared three times)

Programmatic clear from .NET

If a script is mixing PowerShell with raw .NET, System.Console.Clear() does the same thing as cls. This is the call PowerShell itself makes under the hood on Windows.

powershell
[System.Console]::Clear()

Output: (screen cleared)

A C# or PowerShell automation that does not have a real console (e.g. a service or a redirected process) will throw System.IO.IOException: The handle is invalid — check [System.Console]::IsOutputRedirected first.

powershell
if (-not [Console]::IsOutputRedirected) {
    [Console]::Clear()
} else {
    Write-Host "(clear skipped — no console attached)"
}

Output: (screen cleared, or "no console attached")

Clearing inside the Win32 API

Outside of cls, the canonical Win32 sequence is exactly what cmd.exe does internally: query the buffer, write spaces over every cell, write attributes over every cell, then home the cursor. Knowing this helps when writing native console tools or debugging why a PowerShell host like ConEmu or Cmder leaves stale colours after a clear.

c
// Pseudocode — the steps cls executes
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
GetConsoleScreenBufferInfo(hOut, &csbi);
DWORD cells = csbi.dwSize.X * csbi.dwSize.Y;
COORD home = { 0, 0 };
DWORD written;
FillConsoleOutputCharacter(hOut, ' ', cells, home, &written);
FillConsoleOutputAttribute(hOut, csbi.wAttributes, cells, home, &written);
SetConsoleCursorPosition(hOut, home);

Output: (would clear the screen — illustrative, not runnable in cmd)

cls and ANSI colour state

A common surprise: after running a coloured-output program like winget or git, the console may keep the last colour as the default fill for the next cls. The fix is to emit ESC[0m (reset attributes) before clearing.

powershell
# Reset colours, then clear — guarantees a clean white-on-black canvas
Write-Host "`e[0m" -NoNewline
Clear-Host

Output: (screen cleared with default colours)

In cmd.exe, the equivalent is color (no argument) before cls:

cmd
color
cls

Output:

perl
(colours reset, then screen cleared)

cls is useless in redirected output

cls writes to the console handle, not stdout, so capturing it does nothing useful. Worse, mixing it into a script that may sometimes run with redirected output (logging to a file) creates inconsistent files — the cls is invisible in the file but breaks interactive sessions if removed.

cmd
rem Bad: this script behaves differently when piped vs interactive
@echo off
cls
echo Build complete.

Output: (none — this is the script body, not invocation)

cmd
rem Run the same script interactively vs piped to file
build.bat
build.bat > build.log
type build.log

Output:

code
Build complete.

The file is correct because cls produced no stdout, but anyone reading the script may assume cls left a marker — it did not.

Conditional clear in batch scripts

A robust script should clear only when running interactively. Detecting that is awkward in pure cmd.exe, but checking for an empty %CMDCMDLINE% or for a redirected stdout works.

cmd
@echo off
rem Only clear if stdout is a TTY (not piped/redirected)
fc nul nul > nul 2>&1
if errorlevel 1 (
    cls
)
echo Starting...

Output:

code
Starting...

In PowerShell the same idea is one-liner and idiomatic:

powershell
if (-not [Console]::IsOutputRedirected) { Clear-Host }
Write-Host "Starting..."

Output:

code
Starting...

cls and the prompt variable

cls resets the cursor to the top of the buffer, but the next command will re-emit the prompt. If the prompt contains escape codes (set with prompt $E[36m$P$G$E[0m for a cyan prompt), those colours are re-applied each line. There is no interaction between cls and prompt — but be aware that prompt $E[2J$E[H would create a prompt that clears the screen on every keystroke (almost certainly not what you want).

cmd
rem Save and restore the prompt around an inline clear
set OLD_PROMPT=%PROMPT%
prompt $G
cls
echo Hello
prompt %OLD_PROMPT%

Output:

code
Hello

Animation with cls (don't do this)

Calling cls in a tight loop to animate text causes severe flicker because the entire buffer is erased before being repainted. The right way is to use VT cursor positioning (ESC[H) to overwrite specific cells rather than clearing first. Compare:

powershell
# Bad — flickers on every frame
while ($true) {
    Clear-Host
    Write-Host "Time: $(Get-Date -Format HH:mm:ss)"
    Start-Sleep -Milliseconds 200
}

Output: (visible flicker)

powershell
# Good — overwrite in place, no clear
[Console]::CursorVisible = $false
while ($true) {
    Write-Host "`e[H`e[KTime: $(Get-Date -Format HH:mm:ss)" -NoNewline
    Start-Sleep -Milliseconds 200
}

Output: (smooth update, no flicker)

ESC[H homes the cursor; ESC[K erases the rest of the line. Together they overwrite a single line without touching the rest of the buffer.

Real-world recipes (continued)

Cross-platform clear in a multi-shell script

A script that must run identically on Windows PowerShell, PowerShell 7, and Bash (under WSL) can branch on the OS.

powershell
if ($IsWindows -or $PSVersionTable.PSVersion.Major -le 5) {
    Clear-Host
} else {
    & clear
}
Write-Host "Starting cross-platform task..."

Output:

sql
Starting cross-platform task...

A reusable function that clears the screen, prints a centred banner, and leaves the cursor below it — useful for batch menus and PowerShell modules alike.

powershell
function Show-Banner {
    param([string]$Title)
    Clear-Host
    $width = [Console]::WindowWidth
    $pad   = [Math]::Max(0, ($width - $Title.Length) / 2)
    Write-Host (' ' * $pad + $Title) -ForegroundColor Cyan
    Write-Host ('=' * $width) -ForegroundColor DarkCyan
}

Show-Banner "Deploy: MyApp v2.1.0 — myhost"

Output:

markdown
                   Deploy: MyApp v2.1.0 — myhost
================================================================

Refresh-every-second status table

A common admin pattern — print a live status table that refreshes every second. Using ESC[H instead of cls keeps the screen flicker-free.

powershell
[Console]::CursorVisible = $false
try {
    while ($true) {
        Write-Host "`e[H" -NoNewline
        Get-Service | Where-Object Status -eq Running |
            Select-Object -First 10 Name, Status |
            Format-Table -AutoSize | Out-String | Write-Host -NoNewline
        Start-Sleep -Seconds 1
    }
} finally {
    [Console]::CursorVisible = $true
}

Output:

sql
Name            Status
----            ------
AudioEndpoint   Running
BFE             Running
...

Clear-and-prompt utility for batch menus

A two-line helper used at the top of every menu screen — cleared, banner, blank line, then prompt.

cmd
@echo off
:menu
cls
echo === Maintenance Menu ===
echo  1. Disk cleanup
echo  2. Check updates
echo  3. View logs
echo  0. Exit
echo.
set /P pick=Select: 
if "%pick%"=="0" exit /b
goto menu

Output:

markdown
=== Maintenance Menu ===
 1. Disk cleanup
 2. Check updates
 3. View logs
 0. Exit

Select:

Clearing inside a remote session

Invoke-Command against a remote host does not have a real interactive console, so Clear-Host is silently skipped (or throws on older PowerShell). When writing a remote script, omit cls and rely on the caller's terminal.

powershell
Invoke-Command -ComputerName myhost -ScriptBlock {
    # Clear-Host here would do nothing useful
    Get-Service | Where-Object Status -eq Running
}

Output:

python-repl
Status   Name               DisplayName
------   ----               -----------
Running  AudioEndpoint      Windows Audio Endpoint Builder
...

Sources

References consulted while writing this article. Links open in a new tab.

  • Microsoft Learn — cls command reference — Authoritative flag list and parameter semantics used to build the Essential options table.
  • SS64 — cls — Cross-version comparison and historical syntax notes.

See also