PowerShellTunnel, what is it and why is it..

While using PowerShell to construct and manipulate .NET objects, did you ever wonder that it would be pretty darn cool to be able to open a PowerShell console and connect to and directly access the objects of a running application (at least the objects it exposes)?

Some things you might want to do:

  1. Ad-hoc debugging, diagnostics, or monitoring.
  2. Changing object properties or calling methods at runtime.
  3. Ad-hoc (or scripted) unit, system, or integrity tests on a live application.
  4. Simulating events and actions.
  5. Perhaps even adding or changing functionality on-the-fly.
  6. … probably many other things you might think of.

There is an existing PowerShell Remoting project which uses a remote service to which you connect to to create a PowerShell host that you talk to through your client connection.  This isn’t quite what what I was after and after hearing that PowerShell 2.0 was coming, decided to wait and see.  So PowerShell 2.0 comes and does have Remoting ability but this is also focused on the administrative desire to summon a PowerShell console on a remote host and control it from the client, but neither approach can connect to an existing application’s embedded PowerShell runspace.

So, after some reading and playing, I had a go and came up with PowerShellTunnel, a project which contains:

  1. Server-side cmdlets allowing you to start a ‘tunnel host’ from a PowerShell console (or any PowerShell runspace).
  2. Client-side cmdlets allowing you to start a ‘tunnel’ (connection) from a PowerShell console or runspace to an existing tunnel host (local or remote) and send scripts to the tunnel host console or runspace.
  3. Tab-expansion ‘works’ in that while typing a script destined for a tunnel host, pressing tab will return tab expansion results from the tunnel host’s runspace.  A gotcha (for now) is that as long as you have a ‘current tunnel’ selected, tab expansion always divert to the current tunnel’s host.
  4. An ordinary ’embeddable’ PowerShell runspace class (hostable by any .NET app) where you explicitly specify what objects to expose (and choosing which PowerShell variable names) and what tunnel hosts to host.
  5. An example of a console application with a few simple objects that you can use to connect to from an ordinary PowerShell console.
  6. WCF is used to do all the legwork of the underlying connection, by default the code uses http.  By using WCF we avoid having to worry about transport options, security, and other issues as this should be all configurable.
  7. WCF-serializable objects can be piped into and out of the tunnel (types unknown to WCF DataContractSerializer need to be registered as known types).
  8. The cmdlets also allow an ordinary PowerShell console to act as a tunnel host (the easiest way to start playing with PowerShellTunnel is to use one PowerShell console as the host and another as the client).  Similarly an embedded runspace could start a tunnel to any tunnel host too.
  9. Any console or runspace can have multiple tunnel hosts and/or can have multiple tunnels open.

To make a long story short, if you want to try it out, I uploaded it to:

http://code.msdn.microsoft.com/PowerShellTunnel

The download is a single PowerShellTunnel.sln (VS2005).  The code gallery site above includes documentation on how to use it too.

Let me know if there is similar technology out there or if PowerShell 2.0’s Remoting can be adapted to this end (but from what I read it cannot – for example it only connects to sessions spawned from that same console which may be remote, but which are not pre-existing or embedded).  Also please comment here or on code gallery with any bugs, ideas, thoughts or pointers.