Webserver and RSH in PowerShell
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.
>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/