April 11th, 2015

A tiny, cross-platform remote PowerShell shell

Yet-Another-Tool in my 6 month journey in avoiding having to use Windows to automate Windows.

— Matthew Fellows —

I’ve spent the last 6 months working in the Windows ecosystem, an unfamiliar territory that eventually led to a fairly lengthy yak shaving exercise building a set of Packer.io plugins for Windows to ultimately create a Vagrant box in a sane way. All of this and I’ve done my absolute best to avoid using Windows as a Desktop/Development environment from a day-to-day basis. Why? It’s hard to pinpoint an exact reason for this – because there are just so many – but for starters:

  • I use Dvorak (yes, I know I know…). Try changing keyboard layouts when pairing – I dare you. The layout ties itself to the current application so alt-tabbing will happily change between them for you. Because, you know, that makes sense. (This is true at least on 2008r2 and probably similarly aged OSs. 2012r2 resolves this)
  • The Shell/Terminal. Oh. My. God. Whilst PowerShell itself is pretty awesome, the terminal is nothing short of pathetic. CMD is even worse. Copy/paste is an exercise in frustration, tab-completion is useless, multi-line select doesn’t exist and the default colour palette and font make absolutely no sense. I mean, errors by default are red text on a blue background – it’s like they want you to simply ignore them. If I had to guess, it was like there was literally no designer involved in the terminal at all.

So, back to the point. Iterating on Windows machines is hard enough, particularly when they are remote (e.g. AWS). When things go wrong there is no SSH and so you end up RDPing a lot – and this slows you down. This led me to create a tiny CLI wrapper around a WinRM library for Go that allowed me to run one-off PowerShell/CMD commands against a remote machine. This was awesome; now I could be free of having to constantly RDP into a GUI (which can trigger tiworker.exe and a slow system).

That led me to thinking if there was a way we could make this more of an interactive shell. So last night on the train I got busy and created one.

It is fairly experimental at this point, and I have no plans in turning it into a fully PoSH integrated shell, but in theory it should be fairly easy to extend to support some handy features that would make it even more useful:

  • Support Secure WinRM communications via certificates
  • History
  • ctrl-r lookup
  • Basic variable interpolation
  • Winrmcp support for simple remote copy/paste