STMA

SSH to PowerShell

Last week I needed to work in PowerShell on a set of remote machines. No problem; the machines had ssh installed! First problem: SSH dumps you into a command prompt, not PowerShell, so you need to run powershell on login every time. Thankfully, ~/.ssh/config (since version 7.6) has an option to do this:

Host windows_server
    RemoteCommand powershell

It works! But: problem! I use a dark theme. The defaults for PSReadLine make the “Operator” and “Parameter” tokens dark gray, also known as invisible or at least heavily obscured against a dark background. Using Get-PSReadLineOption shows the full colorscheme (and other options). Tim Abell has a StackOverflow answer with a script to show all the console colors; I don’t care about seeing each on a different background so I simplified it.

Foreach ($fgcolor in [enum]::GetValues([System.ConsoleColor])) { Write-Host "$fgcolor | " -ForegroundColor $fgcolor -NoNewLine }

We can use Set-PSReadLineOption to change the colors, but once again that means running another command (and a much longer one) after login.

Set-PSReadLineOption -Colors @{
  Member=\"$([char]0x1b)[95m\";
  Number=\"$([char]0x1b)[94m\";
  Operator=\"$([char]0x1b)[97m\";
  Parameter=\"$([char]0x1b)[97m\";
  Type=\"$([char]0x1b)[34m\";
  Variable=\"$([char]0x1b)[35m\"
}

I changed more than just “Operator” and “Parameter” colors to make things a little nicer.

The next step is to cause PowerShell to run this command immediately after login. Note that besides the -Command flag (which must be last), we also need the -NoExit flag so that PowerShell does not immediately quit (ending our ssh session) after setting the proper colors.

Host windows_server
    RemoteCommand powershell -NoExit -Command Set-PSReadLineOption -Colors @{ Member=\"$([char]0x1b)[95m\"; Number=\"$([char]0x1b)[94m\";  Operator=\"$([char]0x1b)[97m\"; Parameter=\"$([char]0x1b)[97m\"; Type=\"$([char]0x1b)[34m\"; Variable=\"$([char]0x1b)[35m\" }

I found that this worked on the most up-to-date servers, but there were some older machines in the environment, and the Set-PSReadLineOption command as written threw errors there. A few machines still had PSReadLine version 1, which used a different syntax to set colors.

Host old_windows_server
    RemoteCommand powershell -NoExit -Command Set-PsReadLineOption -TokenKind None -ForegroundColor White; Set-PsReadLineOption -TokenKind Member -ForegroundColor Magenta; Set-PsReadLineOption -TokenKind Number -ForegroundColor Blue; Set-PsReadLineOption -TokenKind Operator -ForegroundColor White; Set-PsReadLineOption -TokenKind Parameter -ForegroundColor White; Set-PsReadLineOption -TokenKind Type -ForegroundColor DarkBlue; Set-PsReadLineOption -TokenKind Variable -ForegroundColor DarkMagenta

Some others, which seemed to be up-to-date, also did not like the special character syntax so I used color names.

Host other_windows_server
    RemoteCommand powershell -NoExit -Command Set-PSReadLineOption -Colors @{ Member='Magenta'; Number='Blue';  Operator='White'; Parameter='White'; Type='DarkBlue'; Variable='DarkMagenta' }

Using the color names instead of VT escape sequences seemed to work on all the machines, but according to the documentation any number of methods are acceptable, so ¯\_(ツ)_/¯.