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.
help cls
Output:
Clears the screen.
CLS
Syntax
cls takes no arguments.
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.
@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:
==================
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.
@echo off
echo Running installer...
msiexec /quiet /i myapp.msi
cls
echo Installation complete.
Output:
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.
cls > NUL
echo Screen cleared.
Output:
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.
cls
Output: (screen cleared)
Clear-Host
Output: (screen cleared)
Common pitfalls
clsclears 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 callingcls.clsinside a pipe is a no-op —echo text | clsdoes not make sense;clsignores stdin and writes directly to the console.- Redirecting
clsto a file creates an empty file —cls > screen.txtcreates an empty file; the escape sequences go to the console handle, not stdout. - Does not work in non-interactive contexts — when cmd.exe is spawned without a console (e.g. via
CreateProcesswithDETACHED_PROCESS),clsmay fail silently.
Real-world recipes
Interactive loop with periodic clear
@echo off
:loop
cls
echo Current time: %TIME%
echo Press Ctrl+C to exit, any key to refresh.
pause > NUL
goto loop
Output:
Current time: 14:22:05.34
Press Ctrl+C to exit, any key to refresh.
Clear screen at the start of a deployment script
@echo off
cls
echo ===================================
echo Deploy: MyApp v2.1.0
echo Host: myhost
echo Date: %DATE%
echo ===================================
echo.
Output:
===================================
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.
rem Demonstrates that cls writes nothing to stdout
cls > saved.txt
dir saved.txt
Output:
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 — write the ANSI clear sequence directly
$esc = [char]27
Write-Host "$esc[2J$esc[H" -NoNewline
Output: (screen cleared the same as cls)
# 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.
| Sequence | Effect |
|---|---|
ESC[2J | Erase entire screen (cursor stays put) |
ESC[3J | Erase entire screen and scroll-back buffer (Windows 10 1809+) |
ESC[H | Cursor to row 1, column 1 |
ESC[0;0H | Same as above, explicit row/column |
ESC[K | Erase from cursor to end of line |
ESC[1K | Erase from start of line to cursor |
ESC[2K | Erase the entire current line |
ESC[<n>A | Move cursor up n rows |
ESC[<n>B | Move cursor down n rows |
ESC[<n>C | Move cursor right n columns |
ESC[<n>D | Move cursor left n columns |
ESC[s | Save cursor position |
ESC[u | Restore saved position |
ESC[?1049h | Switch to alternate screen buffer (vim-style) |
ESC[?1049l | Switch back to main buffer |
# 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.
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.
| Shell | Command | Implementation |
|---|---|---|
cmd.exe | cls | Internal — Win32 console API |
| PowerShell 5.1 | Clear-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 / Fish | clear | Reads clear capability from terminfo |
| WSL | clear | Same as Bash — uses terminfo |
| Windows Terminal (any shell) | Built-in: Ctrl+L / Ctrl+Shift+K | Renderer API call |
# 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.
| Shortcut | Where it works | What it does |
|---|---|---|
Ctrl+L | PowerShell 5.1+ (PSReadLine), bash, zsh, fish, Windows Terminal | Clears visible viewport, keeps scroll-back |
Ctrl+Shift+K | Windows Terminal (all profiles) | Clears the entire buffer (visible + scroll-back) |
Cmd+K | iTerm2, Apple Terminal | Clears scroll-back too |
| Right-click → Clear Buffer | Windows Terminal title bar menu | Same as Ctrl+Shift+K |
cls / clear | cmd / PowerShell / bash | Visible 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.
| Feature | conhost.exe | Windows Terminal |
|---|---|---|
cls behaviour | Clears visible viewport | Clears visible viewport |
ESC[2J support | Yes (Windows 10 1607+) | Yes |
ESC[3J (scroll-back wipe) | Windows 10 1809+ | Yes |
Scroll-back retained after cls | Yes (mouse wheel up) | Yes |
| Alternate screen buffer | Limited | Full |
Keyboard Ctrl+L | No | Yes (in PSReadLine shells) |
Ctrl+Shift+K | No | Yes (clears all) |
| Renderer | GDI | DirectWrite (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.
Get-Command Clear-Host | Format-List *
Output:
CommandType : Function
Name : Clear-Host
Definition : ...uses [Console]::Clear() on Windows...
Module :
...
# Inspect the function body
(Get-Command Clear-Host).ScriptBlock
Output:
$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.
# 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.
[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.
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.
// 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.
# 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:
color
cls
Output:
(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.
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)
rem Run the same script interactively vs piped to file
build.bat
build.bat > build.log
type build.log
Output:
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.
@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:
Starting...
In PowerShell the same idea is one-liner and idiomatic:
if (-not [Console]::IsOutputRedirected) { Clear-Host }
Write-Host "Starting..."
Output:
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).
rem Save and restore the prompt around an inline clear
set OLD_PROMPT=%PROMPT%
prompt $G
cls
echo Hello
prompt %OLD_PROMPT%
Output:
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:
# 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)
# 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.
if ($IsWindows -or $PSVersionTable.PSVersion.Major -le 5) {
Clear-Host
} else {
& clear
}
Write-Host "Starting cross-platform task..."
Output:
Starting cross-platform task...
Banner-and-clear startup helper
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.
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:
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.
[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:
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.
@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:
=== 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.
Invoke-Command -ComputerName myhost -ScriptBlock {
# Clear-Host here would do nothing useful
Get-Service | Where-Object Status -eq Running
}
Output:
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
- bcdedit — Boot Configuration Data Editor — the boot store cleaner that often runs from a freshly cleared admin prompt.
- echo — Output Text and Control Command Echo — paired with
clsfor batch menu rendering. - PowerShell Essentials —
Clear-Host,$Host.UI.RawUI, and PSReadLine keybindings. - dism — Deployment Image Servicing and Management — long-running deployments often
clsbetween phases for clarity.