Webserver and RSH in PowerShell

Home  >>  Cool  >>  Webserver and RSH in PowerShell

Webserver and RSH in PowerShell

On January 24, 2007, Posted by , In Cool,PowerShell, With 1 Comment

Ever wanted to control a PowerShell session from a web browser or curl/wget on another machine?

Yes? Well it surprisingly simple using PowerShell to script the System.Net.HttpListener. Here’s a working example with some genuine uses (well useful for me).

I’ll leave all the security and risk concerns as an exercise for the reader 🙂

What we have here is a small PowerShell script, httpd.ps1, that listens on a port of your choosing (default 8888) using the HTTP protocol, executes supplied PowerShell expressions, the returns the pipeline output to the caller.

To use it, type this in a PowerShell window:

./httpd

This will set the web server listening on http://yourhostname:8888/. You can change this to be something else by supplying a prefix as a parameter, eg:

./httpd http://192.168.0.28:8888/

or safer (in case it crashes)

powershell -command ./httpd http://192.168.0.28:8888/

This parameter must end in a slash.

You’ll need to open the appropriate port in your firewall, if you intend to try to use this from a different machine.

Once running (and using that example above) you can enter that url into your web browser, and the response you’ll get should be something like:

No command supplied.

Syntax is: http://server/?cmd=xxxx

Where xxxx is 'quit' to tell the server to quit
or any PowerShell command.

Eg:  http://server/?cmd=get-process

You can see from this that you need to supply a command. Try this:

http://192.168.0.28:8888/?cmd=get-process

What you get back is a process listing for the host machine.

I use this mostly with the command line tool curl to get command output on my Mac, eg:

macpro:~ adrian$ curl -g 'http://192.168.0.21:8888/?cmd=ps|where%20{$_.ws%20-gt%2010mb}'

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    836      15    42864      55092   236     8.58   3440 dexplore
    512      14    15736      27316    94    17.20   1512 explorer
    192       6    16092      11160   126     0.12   2748 httpd.vshost
    657      17    20224      31776   112    10.32   3792 iexplore
    419      14     6680      11564    75     9.12   1412 KService
   1004       6    45232      43740   156     2.93   3324 powershell
    185       5    22108      28624   126     0.54   3368 powershell
    163       7    35812      34668   138     1.74   3640 powershell
   1588      57    45812      54516   231   495.46    808 svchost

You have to escape the URL for curl, but this executed ps|where {$_.ws -gt 10mb} (all processes with a working set greater than 10mb).

Note that this script does not show you the output from write-host or any errors, but if you ask for $Error you will get the recent errors returned.

An alternative would be to modify the script to use get-bufferhtml to return a full copy of the PowerShell buffer.

Anyways, I learned how easy it is to write a mini web server in .NET and PowerShell, so I’m happy 🙂

Oh, one last thing. To stop the script, send it a cmd=quit. You could just ctrl+break in the PowerShell window, but I find that causes the whole host to disappear.

One Comment so far:

  1. lb says:

    >I’ll leave all the security and
    >risk concerns as an exercise for
    >the reader

    oooh! you are nasty!

    nice work 😉

    note there’s some other example Powershell webservers: http://www.viveksharma.com/techlog/2005/12/08/serving-up-pages-msh-style/