‹ Guides

Connecting to a Windows server

Windows answers SSH with cmd or PowerShell rather than a Linux shell. Nearly everything works the same — but colours in coding agents and other full-screen tools come out wrong until you set one thing on the Windows side.

Written

What it looks like

On a Windows server, a coding agent’s panels arrive in flat slabs of colour. A nearly-black background turns solid green, greys go muddy, and the soft tints a diff uses for added and removed lines collapse into the same two or three colours. Everything is readable; it simply is not what the program meant to draw. btop, lazygit, bat and delta do the same thing.

The giveaway is that the same program on a Linux or macOS server looks right — from the same phone, in the same colour scheme. So it is not the program, and it is not the terminal theme you picked.

Why it happens

Your terminal can draw about 16 million colours. A program will not assume that — it looks for a marker in the environment it was started in, and if nothing says otherwise it drops to a 256-colour set and picks the closest match it can for every colour it wanted. “Closest match” is what turns a nearly-black panel into a green slab.

On Linux and macOS servers Term sets that marker for you as the session opens. It cannot on Windows: cmd and PowerShell do not understand the line it would use, and typing something into your prompt that only comes back as an error would be worse than the wrong colours. So on a Windows machine the marker has to be set once, on that machine — and then it is there for every session, from Term or anything else.

The fix — one line on the Windows machine

Get to the Windows machine — at the keyboard, or over a Term session — as the account you log in with over SSH, and run this in PowerShell:

PowerShell, on the Windows machine
setx COLORTERM truecolor
  1. It sets an environment variable called COLORTERM to truecolor, permanently, for your account. Nothing else on the machine changes.
  2. Run it as the account SSH logs in as. One set under a different user, or machine-wide, may not reach your session.
  3. Disconnect and connect again from Term. It applies to new sessions, not to the one you are sitting in.

Still flat after reconnecting? The SSH service is holding an older copy of the environment. Restart it from an Administrator PowerShell — this drops any other SSH sessions on that machine:

Administrator PowerShell
Restart-Service sshd

Two other ways

If you would rather not touch the account’s environment, put it in your PowerShell profile instead. This one covers PowerShell sessions only — a session that lands in cmd will not see it:

PowerShell, on the Windows machine
if (-not (Test-Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force }
Add-Content $PROFILE '$env:COLORTERM = "truecolor"'

And if you administer the server, you can let the setting come from the client instead. Term already offers COLORTERM alongside your locale and a light/dark hint; the server simply has to be willing to accept them. Add this line, then restart the service as above:

C:\ProgramData\ssh\sshd_config
AcceptEnv LANG LC_* COLORTERM COLORFGBG

This route has a second benefit: it is also what makes the per-host Environment variables field work on a Windows host. The note under that field in the app says the same thing.

Check it — and what is left if it is still wrong

Open a session and ask the machine directly. The first line is for PowerShell, the second for cmd:

On the Windows machine
echo $env:COLORTERM
echo %COLORTERM%

Blank means it has not arrived yet — go back a section. truecolor means it has, and anything still wrong is no longer about this setting.

What is left is Windows itself. Console output on a Windows server is redrawn by a layer of the operating system before it reaches the network, and older builds of that layer flatten colours no matter what the program sent. Updating Windows and its OpenSSH component is the fix; where that is not possible, the last section is.

What else is different on a Windows host

Command suggestions are off

The greyed-out suggestion as you type needs a Linux or macOS shell to work with, so there is nothing to switch on here. PowerShell has its own history search instead — ^R is on the key bar for it.

Term will not install a key for you

Windows hosts are left out of the list when you generate a key. Windows keeps authorised keys somewhere else, with different permissions, and for an administrator account in a different file altogether — so a one-tap install would quietly write the wrong file and report success. Add the key on the Windows machine yourself.

The key bar changes

Term notices it is talking to a Windows shell, and the extra keys become the ones those shells want: \ and - for paths and parameters, |, $, and ^R for history search.

Per-host environment variables need the server’s permission

Variables you set on a host under Advanced options reach a Linux server by themselves. On Windows they travel the same road as COLORTERM above, so they arrive only once the server has been told to accept them.

The shortcut: point SSH at WSL

If the machine has WSL, making it the shell SSH logs you into retires this entire page. Colours, suggestions, key installs and environment variables all behave the way they do on any Linux server, because from Term’s side that is what you are connected to. The setting is OpenSSH’s default shell, in the registry at HKLM:\SOFTWARE\OpenSSH\DefaultShell.

One caution, and it applies to any change to what SSH logs you into: keep your current session open and test with a second one. If the new shell does not start, the session you still have is how you put it back.