Yay! Console host enhancements! Wait… what is the console host? Is that cmd.exe? Or do you mean powershell.exe? It’s neither of these things and it’s both of these things, and more. Ok, I’m just making it more confusing. PowerShell runs in a cmd window, right? Nope. Cmd runs in powershell window? Nope, that’s not right either. Both of these applications are “console mode” applications. They both use the Windows Console subsystem. PE executables (EXEs) have a bit in the header which tells Windows whether it’s a GUI or a console app. Anyway, if it’s a console app, it uses a special process called ConHost.exe This hosting process provides the features of what some people mistakenly call the “cmd window,” or “command window.” So, resizing (yay Windows 10,) quick edit, copy, paste, selection, colours etc.
The Olden Days
This probably isn’t news to you. After all, the inimitable Scott Hanselman blogged about the new console features back in 2014. If you’re an old guy like me, you probably look at the new stuff and think: “Sheesh, about time, but meh, it’s still so lacking.” I remember back when we had no cell phones, and the internet was about ten computers tied together with acoustic couplers and a prayer, and back then our consoles were much more capable. They had cool stuff like ansy.sys drivers, that would let us embed control codes into the text itself to move the cursor around, set colours and generally “gussy up” console output without having to fiddle with APIs. Back when DECs Vaxen roamed the universities of old, people used to make animated text files – think it of an old-school ascii art giphy. Anyway, there is a very cool console emulator that hosts windows console mode apps like cmd and powershell called ConEmu. It has a cool feature where it can inject some hooks into the process to enable ANSI escape sequence processing. Nice, but again, it only works when you use ConEmu.
Still, it’s pretty nice and lets you do much more than that. But anyway, moving on.
Open SSH, ANSI and VT100 Terminals
Yes, yes, we know – Scott told us about that too. Open SSH is coming to Windows. Who cares? Open SSH clients are a dime-a-dozen, even on Windows. But wait… this is not just a client. It’s an Open SSH server too – and not just a rough port. Although last year, the one Scott showed looked fairly rough:
Well, it looks rough, sure. For one thing, there’s no colour support. So how does that work on other operating systems, like Linux? Well, Unix terminals are far smarter beasts than the Windows terminal (i.e. the console host.) They understand ansi and vt100 escape sequences, just like Windows 95 used to do about twenty years ago (well, Windows just understood a subset of ANSI.) What sort of things do these escape sequences let you embed into text? Well, most advanced terminals on Unix understand sequences to change background and foreground colours, move the cursor around, query terminal capabilities, beep, erase text, set attributes like blink, underline, emphasis (bright / dim) etc. Some even can do italics and bold.
So, the goal of Microsoft working on an integrated implementation of OpenSSH for Windows is to allow anyone with an SSH client to remote into a Windows box and run powershell or cmd, or any other console mode application and manage the computer. The thing is, SSH clients like to send lots of escape sequences to control the rendering of the screen to the user, and expects the program on the far side to send them back so it can portray information in a pretty, or at least legible way. It’s a screen-oriented system, not a line-oriented one like the current PowerShell remoting is. It acts like a full, native on-the-box terminal, not like a 1980s edlin input loop. You know, if Microsoft shipped an OpenSSH server and native client that could only offer line-oriented, monochrome interaction, people would just give up entirely and stick to using PuTTY.
It’s a good thing they’re not doing that.
Escape Sequences are Back, Baby!
So, yeah, I just blew the surprise in a single heading but yep. I found out completely by accident when I was playing with an ansi file and I realized I wasn’t even using ConEmu. I did a complete double-take and then did some research.
So what works?
Well, a large proportion of ANSI & VT100 escape sequences have been implemented. They are handled at the console host layer (conhost.exe), and not within cmd or powershell. This allows any console mode applications to be exposed through an SSH connection, and they will have enhanced interactivity if they know how to speak terminal-talk escape sequences. I didn’t go through all of the sequences to test, but most, if not all of cursor and colour handling works although it’s still just a16 colour terminal (not 256 color, yet?). Also terminal interrogation works, as does underline, reverse-video, intensity and dim and some other attributes that historically have not worked under windows although the non-functioning attributes were always documented on MSDN.
One thing you’ll notice though is that while it works for prompt functions and raw output in cmd.exe, it doesn’t work out of the box for powershell.exe. This is a pity, but I managed to figure out the undocumented flags used by cmd.exe to enable the functionality in conhost.exe.
How to enable ANSI & VT100 Escape Sequence Processing
There’s a new undocumented bit – 0x04 – you can flip when calling SetConsoleMode. Here’s a script to enable it in PowerShell:
Add-Type -MemberDefinition @"
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, int mode);
public static extern IntPtr GetStdHandle(int handle);
public static extern bool GetConsoleMode(IntPtr handle, out int mode);
"@ -namespace win32 -name nativemethods
$h = [win32.nativemethods]::getstdhandle(-11) # stdout
$m = 0
$success = [win32.nativemethods]::getconsolemode($h, [ref]$m)
$m = $m -bor 4 # undocumented flag to enable ansi/vt100
$success = [win32.nativemethods]::setconsolemode($h, $m)
Also, if you start powershell.exe from cmd.exe, it will inherit the conhost settings since it’s attaching to a previously created console, not allocating a new one; this also enables escape sequences in powershell.exe.
I assume that at some point in the future this will be documented publically. It’s enabled at such a foundational level in Windows, it’s clear this is destined to become a public API.
Of course, embedding extra control characters into text in PowerShell will confuse its formatter as it will count the hidden characters when computing column widths etc. So, while you can technically create colourized formatdata now, it won’t really work so well until Microsoft get around to fixing this (which I assume they will at some point in the future.) This is likely why powershell.exe does not enable the enhanced console mode by default.
Exciting times, and I mean that without a shred of irony. I await the day when we can switch away from all of this nasty MAML and start writing our PowerShell help in Markdown, and use an inline console Markdown viewer to browse and read colourized, fancy output in our remote terminals over SSH.
In the meantime, you can head on over to textfiles.com and knock youself out “type”-ing the various 1970s archived VT100 text file animations from the cmd.exe window and laughing to yourself like you’re minus 25 years old again (some go too fast to notice, some don’t work, some depend on console width – remember, some of these files are over 40 years old!)