<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>ps1.soapyfrog.com</title>
	<atom:link href="http://ps1.soapyfrog.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ps1.soapyfrog.com</link>
	<description>doing inappropriate things with powershell</description>
	<pubDate>Sun, 26 Aug 2007 22:01:08 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Grrr source code, including Invaders</title>
		<link>http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/</link>
		<comments>http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/#comments</comments>
		<pubDate>Sun, 26 Aug 2007 16:24:46 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Announce]]></category>

		<category><![CDATA[Grrr]]></category>

		<category><![CDATA[Invaders]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/</guid>
		<description><![CDATA[As you may have noticed, there has been very little activity here from me in recent months.
This is partly because my full time work does not use nor need PowerShell and my free time has become more precious.
Playing with PS1 has been fun and I&#8217;ve learned a lot, but ultimately, it&#8217;s just a toy to [...]]]></description>
			<content:encoded><![CDATA[<p>As you may have noticed, there has been very little activity here from me in recent months.</p>
<p>This is partly because my full time work does not use nor need PowerShell and my free time has become more precious.</p>
<p>Playing with PS1 has been fun and I&#8217;ve learned a lot, but ultimately, it&#8217;s just a toy to me, and there comes a time when you must put your toys away &#8212; one might argue that, at nearly 40, I should have put my toys away long ago <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Now, I&#8217;ve been inundated with literally 3 requests for the source code to <a href="http://ps1.soapyfrog.com/category/grrr/">Grrr</a>, the snapin-based framework behind <a href="http://ps1.soapyfrog.com/2007/02/26/grrr-11-and-big-invaders/">Big Invaders</a>, so here it is:</p>
<p><strong><a href='http://ps1.soapyfrog.com/wp-content/uploads/2007/08/grrr-303.zip' title='Grrr source code'>Grrr source code</a><br />
</strong></p>
<p>Like the rest of the stuff here, it&#8217;s released under the creative commons license.</p>
<p>So long, and thanks for all the fish.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/08/26/grrr-source-code-including-invaders/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Google going down the pan</title>
		<link>http://ps1.soapyfrog.com/2007/04/01/google-going-down-the-pan/</link>
		<comments>http://ps1.soapyfrog.com/2007/04/01/google-going-down-the-pan/#comments</comments>
		<pubDate>Sun, 01 Apr 2007 07:36:16 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/04/01/google-going-down-the-pan/</guid>
		<description><![CDATA[Not PowerShell related in any way (unless you can think of something) but this did make me laugh.
http://www.google.com/tisp/
I especially like the FAQ on why it&#8217;s free 
]]></description>
			<content:encoded><![CDATA[<p>Not PowerShell related in any way (unless you can think of something) but this did make me laugh.</p>
<p><a href="http://www.google.com/tisp/">http://www.google.com/tisp/</a></p>
<p>I especially like the FAQ on why it&#8217;s free <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/04/01/google-going-down-the-pan/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cmdlet clashes</title>
		<link>http://ps1.soapyfrog.com/2007/03/06/cmdlet-clashes/</link>
		<comments>http://ps1.soapyfrog.com/2007/03/06/cmdlet-clashes/#comments</comments>
		<pubDate>Tue, 06 Mar 2007 09:56:22 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cmdlets]]></category>

		<category><![CDATA[Grrr]]></category>

		<category><![CDATA[Hint]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/03/06/cmdlet-clashes/</guid>
		<description><![CDATA[One of the things that struck me whilst developing Grrr as a snapin is: what do you do when you have a cmdlet with the same verb-noun pair as an existing cmdlet?
If someone else had a cmdlet called, say, out-banner, and that cmdlet was already loaded in a snap-in (perhaps mandated by site policy), would [...]]]></description>
			<content:encoded><![CDATA[<p>One of the things that struck me whilst developing <a href="/category/grrr/">Grrr</a> as a snapin is: what do you do when you have a cmdlet with the same verb-noun pair as an existing cmdlet?</p>
<p>If someone else had a cmdlet called, say, <code>out-banner</code>, and that cmdlet was already loaded in a snap-in (perhaps mandated by site policy), would I be able to register and add the Grrr snapin, which also defines it?</p>
<p>I&#8217;ve scanned the available documentation and the language grammar, used introspection in the shell and so on, but could not find anything to deal with this problem.</p>
<p>With projects like <a href="http://www.codeplex.com/PowerShellCX">PowerShell Community Extensions</a> seemingly laying claim to hundreds of common nouns and verbs, I was concerned that the scope for writing unique cmdlets would dry up real fast.</p>
<p><span id="more-62"></span></p>
<p>To determine what would happen, I <a href="/2007/02/26/grrr-11-and-big-invaders/">registered and added</a> <code>Soapyfrog.Grrr</code>, then wrote a new snapin, <code>Soapyfrog.Conflict</code>, with a single cmdlet, <code>out-banner</code>, conflicting with the one in Grrr.</p>
<p>I registered and added this, and was surprised that no warning of a conflict was given. To see if both were added, I tried this:</p>
<pre style='color: #000; background-color: #ccc; '>PS&gt; get-command out-banner

CommandType     Name                        Definition
-----------     ----                        ----------
Cmdlet          Out-Banner                  Out-Banner [-Text] <span>&lt;</span>Str...
Cmdlet          Out-Banner                  Out-Banner [-Text] <span>&lt;</span>Str...
</pre>
<p>Interesting. Both are available, so what happens when I try to invoke it?</p>
<pre style='color: #000; background-color: #ccc; '>PS&gt; out-banner hello
<span style='color: #800; background-color: #ccc'>The term &#39;out-banner&#39; resolved to a cmdlet name that is ambiguous. Pos</span>
<span style='color: #800; background-color: #ccc'>sible matches include: Soapyfrog.Grrr&#x5c;Out-Banner soapyfrog.conflict&#x5c;Ou</span>
<span style='color: #800; background-color: #ccc'>t-Banner.</span>
<span style='color: #800; background-color: #ccc'>At line:1 char:11</span>
<span style='color: #800; background-color: #ccc'>+ out-banner  <span>&lt;</span><span>&lt;</span><span>&lt;</span><span>&lt;</span> hello</span>
</pre>
<p>OK, so at this point, we know it&#8217;s possible to break existing PowerShell scripts by simply registering and adding a new snapin with a same-named cmdlet. Not good. Is there a work-around?</p>
<pre style='color: #000; background-color: #ccc; '>PS&gt; Soapyfrog.Grrr&#x5c;out-banner hello -fg &#39;o&#39;
o   o ooooo o     o      ooo
o   o o     o     o     o   o
ooooo ooo   o     o     o   o
o   o o     o     o     o   o
o   o ooooo ooooo ooooo  ooo
</pre>
<p>Yes! We can fully qualify the cmdlet name with the snapin name and a backslash.</p>
<p>So, it&#8217;s not as bad as I first feared, but as I noted above, you need to be very careful about how you code and run scripts in environments where you can&#8217;t predict what snapins are registered and installed.</p>
<p>I suppose you can create the correct shell environment with Export-Console and run your script with:  </p>
<p><code>powershell -psconsolefile xxx.psc1 -noprofile -command myscript.ps1</code></p>
<p>Or if your script requires a snapin, add the snapin in the script and fully qualify each cmdlet you use.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/03/06/cmdlet-clashes/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Grrr 1.1 and Big Invaders</title>
		<link>http://ps1.soapyfrog.com/2007/02/26/grrr-11-and-big-invaders/</link>
		<comments>http://ps1.soapyfrog.com/2007/02/26/grrr-11-and-big-invaders/#comments</comments>
		<pubDate>Mon, 26 Feb 2007 16:29:41 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Announce]]></category>

		<category><![CDATA[Cmdlets]]></category>

		<category><![CDATA[Cool]]></category>

		<category><![CDATA[Grrr]]></category>

		<category><![CDATA[Invaders]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/02/22/grrr-11-and-big-invaders/</guid>
		<description><![CDATA[So I&#8217;ve been spending a bit of time getting to grips with Cmdlets and resurrecting interest in PSInvaders using Grrr and now have something to post.
Grrr 1.1 is now Cmdlet based and comes as a Snap-In. The most obvious benefit from this is performance, as I can now present a playable version of PowerShell Big [...]]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been spending a bit of time getting to grips with Cmdlets and resurrecting interest in <a href="http://ps1.soapyfrog.com/2007/01/02/space-invaders/">PSInvaders</a> using <strong>Grrr</strong> and now have something to post.</p>
<p><strong>Grrr 1.1</strong> is now Cmdlet based and comes as a Snap-In. The most obvious benefit from this is performance, as I can now present a playable version of <strong>PowerShell Big Invaders</strong>.</p>
<p><a href='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/biginvaders-11-inplay.gif' title='BigInvaders 1.1 in play'><img src='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/biginvaders-11-inplay-smooth.jpg' alt='BigInvaders 1.1 in play' /></a></p>
<p>BigInvaders is one of the demo PowerShell scripts that makes use of the Grrr.</p>
<p><strong><a href="http://ps1.soapyfrog.com/downloads/grrr-release-1.1.zip">Download this prerelease version 1.1 of the Grrr snap-in.</a></strong></p>
<p><em>Update: this should now install on Vista - thanks to Chris Warwick for pointing out some issues</em></p>
<p>There&#8217;s no installer (yet) so to get going, follow this instructions:</p>
<p>Unzip the archive where you want to use it and CD to the top level director where the README file is.</p>
<p>Type: <code>./installgrrr.ps1 -r</code></p>
<p>The <code>-r</code> switch forces it to re-register the snap-in if a (possibly) older version exists. It then adds the snap-in to the current shell.</p>
<p>From here you can CD into the <code>demos</code> directory and run any of the scripts. Each one shows a feature of Grrr, but perhaps the most interesting is in the <code>biginvaders</code> directory.</p>
<p>To run BigInvaders, you need to have a very large console. To achieve this you probably need to set the font size of your console window to 6&#215;8.</p>
<p>If you want sound, you need to install <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=2DA43D38-DB71-4C1B-BC6A-9B6652CD92A3&#038;displaylang=en">DirectX DirectSound</a>. More on why later.</p>
<p>It should work without, silently, but this hasn&#8217;t had much testing as all my XP boxes have it installed <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> If there are exceptions, start it with the <code>-nosound</code> switch.</p>
<p>Assuming all is well, type <code>./biginvaders.ps1</code> and you should see this title screen:</p>
<p><a href='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/biginvaders-11-intro.gif' title='BigInvaders 1.1 intro screen'><img src='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/biginvaders-11-intro.thumbnail.gif' alt='BigInvaders 1.1 intro screen' /></a></p>
<p>Hit ESC to quit or Space to play. In play, Space fires a missile and arrow keys move left and right. Hit F to toggle FPS display in the top-righthand corner. </p>
<p>The target FPS is 33. I achieve this easily on my MacPro, and my wife&#8217;s Dell (a core 1 duo, 1.66ghz) also just manages.</p>
<p>There are still a few snags to iron out here and I want to add proper PowerShell help and an installer, but it is functional.</p>
<p>I&#8217;ve learned a lot about C#, PowerShell SDK and .NET these last weeks and will write about my findings over the next days. It&#8217;s not all been rosy.</p>
<p>I&#8217;ll also be writing about the features of <strong>Grrr</strong>, and where I want to go with it.</p>
<p>That&#8217;s it for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/02/26/grrr-11-and-big-invaders/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Grrr, Cmdlets and PSInvaders revival</title>
		<link>http://ps1.soapyfrog.com/2007/02/15/grrr-cmdlets-and-psinvaders-revival/</link>
		<comments>http://ps1.soapyfrog.com/2007/02/15/grrr-cmdlets-and-psinvaders-revival/#comments</comments>
		<pubDate>Thu, 15 Feb 2007 16:09:53 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Announce]]></category>

		<category><![CDATA[Grrr]]></category>

		<category><![CDATA[Invaders]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/02/15/grrr-cmdlets-and-psinvaders-revival/</guid>
		<description><![CDATA[Still not much happening here, again partly due to being busy with other things, and also the final arrival of my Wii.
Anyways, I&#8217;ve almost completed the transition of Grrr to Cmdlets and it&#8217;s looking very promising as this screen shot shows (I get 50fps with only 20% cpu load doing this):

I intend to redo the [...]]]></description>
			<content:encoded><![CDATA[<p>Still not much happening here, again partly due to being busy with other things, and also the final arrival of my <a href="http://blog.soapyfrog.com/category/wii/">Wii</a>.</p>
<p>Anyways, I&#8217;ve almost completed the transition of <a href="http://ps1.soapyfrog.com/2007/01/03/grrr/">Grrr</a> to Cmdlets and it&#8217;s looking very promising as this screen shot shows (I get 50fps with only 20% cpu load doing this):</p>
<p><a href='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/grrr-invaders-wip.gif' title='Big Invaders'><img src='http://ps1.soapyfrog.com/wp-content/uploads/2007/02/grrr-invaders-wip.thumbnail.gif' alt='Big Invaders' /></a></p>
<p>I intend to redo the original <a href="http://ps1.soapyfrog.com/2007/01/02/space-invaders/">PSInvaders</a> using Grrr, with more authentic gameplay and original graphics. </p>
<p>The scrolling tilemap support is looking good, so games like Gauntlet, Scramble and Super Mario Brothers should be possible&#8230; all scripted in PowerShell.</p>
<p>So apologies for the low post volume recently and please do watch this space.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/02/15/grrr-cmdlets-and-psinvaders-revival/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Slow week</title>
		<link>http://ps1.soapyfrog.com/2007/02/09/slow-week/</link>
		<comments>http://ps1.soapyfrog.com/2007/02/09/slow-week/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 09:45:27 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Announce]]></category>

		<category><![CDATA[Grrr]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/02/09/slow-week/</guid>
		<description><![CDATA[Not much happening here on the blog this week as I&#8217;ve been a bit busy with other things and also on some non-trivial PowerShell projects:

A snap-in version of Grrr - I realised that PowerShell alone is just too slow for it to be useful, so thought I&#8217;d have a go at doing it all as [...]]]></description>
			<content:encoded><![CDATA[<p>Not much happening here on the blog this week as I&#8217;ve been a bit busy with other things and also on some non-trivial PowerShell projects:</p>
<ul>
<li>A snap-in version of <a href="http://ps1.soapyfrog.com/category/grrr/">Grrr</a> - I realised that PowerShell alone is just too slow for it to be useful, so thought I&#8217;d have a go at doing it all as cmdlets in a snap-in. It&#8217;s fairly easy, but I&#8217;m not there yet.</li>
<li>In trying to understand the grammar of PowerShell better (the <a href="http://blogs.msdn.com/powershell/archive/2006/05/10/594535.aspx">documentation</a> is not so great, and Bruce hasn&#8217;t printed his <a href="http://www.manning.com/payette/">book</a> yet), I&#8217;ve started to write an interpreter in Java. I&#8217;ve got a more or less complete AST, and a prototype interpreter, but it&#8217;s slow going (well, I only started 4 days ago, and it&#8217;s in my spare time).</li>
</ul>
<p>Watch this space.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/02/09/slow-week/feed/</wfw:commentRss>
		</item>
		<item>
		<title>IRC chat bot and monitor</title>
		<link>http://ps1.soapyfrog.com/2007/01/31/irc-chat-bot-and-monitor/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/31/irc-chat-bot-and-monitor/#comments</comments>
		<pubDate>Wed, 31 Jan 2007 14:52:16 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Utility]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/31/irc-chat-bot-and-monitor/</guid>
		<description><![CDATA[Last weekend, I asked my wife if she could think of anything inappropriate or unusual to do with PowerShell. She came up with some good ideas and one of them was to write a chat/IM client.
A full client takes time, so with a nod toward PowerShell&#8217;s administrative uses, I wrote a script that forms the [...]]]></description>
			<content:encoded><![CDATA[<p>Last weekend, I asked my wife if she could think of anything inappropriate or unusual to do with PowerShell. She came up with some good ideas and one of them was to write a chat/IM client.</p>
<p>A full client takes time, so with a nod toward PowerShell&#8217;s administrative uses, I wrote a script that forms the basis of an <a href="http://www.faqs.org/rfcs/rfc1459.html">IRC</a> chat bot.</p>
<p>This script can be used to pipe messages to a chat channel and/or join a set of channels, returning all messages posted there.</p>
<p>I&#8217;ve sure most of you out there use <del>Microsoft</del> <del>MSN</del> Windows Live Messenger, or even Yahoo! or AOL, so this may just serve as an example of synchronous TCP/IP messaging in PowerShell.</p>
<p><strong>You can download the script here: <a href='http://ps1.soapyfrog.com/wp-content/uploads/2007/01/chat-ircps1.txt' title='chat-irc.ps1'>chat-irc.ps1</a>. </strong></p>
<p>You may need to unblock it according the the instructions in <code>help about_signing</code>.</p>
<p><span id="more-52"></span></p>
<p><strong>Summary of use</strong></p>
<p>This script operates in two modes, sender, or monitor (or both).</p>
<p>Regardless, you need to set up connection info in a hash, eg:</p>
<pre>$coninfo = @{
  server="chat.freenode.net"
  port=6667
  nick="mynick"
  user="myuser"
  pwd="my password if required"
  realname="This is my real name"
  hostname"This is my host name, but is generally ignored"
}
</pre>
<p> <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_idea.gif' alt=':idea:' class='wp-smiley' /> I&#8217;ve been using chat.freenode.net and my own local hybrid irc server for testing.</p>
<p>To send a message to the #test channel and quit:</p>
<p><code>chat-irc -coninfo $coninfo -sendto "#test" -message "Hello, world"</code></p>
<p>To send output from the pipeline, eg a file:</p>
<p><code>gc file.txt | chat-irc -coninfo $coninfo</code></p>
<p>To monitor a channel for messages:</p>
<p><code>chat-irc -coninfo $coninfo -monitor "#test"</code></p>
<p>This will stay connected until you ctrl+C, are killed by the server, etc, or if <code>chat-irc</code> is sent the message &#8220;stopstopstop&#8221;.</p>
<p>The output is formatted strings containing from/to/message, however these strings are annotated with noteproperties, so you can do:</p>
<p><code>chat-irc -coninfo $coninfo -monitor "#test" select *</code></p>
<p>The properties include sender info (<code>user</code>,<code>host</code>,<code>nick</code>,<code>full</code>), <code>date</code>, <code>to</code> and <code>message</code>.</p>
<p>These two modes can be used together, and the monitor parameter can take<br />
more than one channel, so for example:</p>
<p><code>chat-irc -coninfo $coninfo -monitor "#foo","#bar" -sendto "#test" -message "hello"</code></p>
<p>will send &#8220;hello&#8221; to #test then monitor #foo,#bar and #test for messages.</p>
<p>By default, only messages sent to the monitored channel(s) are output, but you can include private messages with the switch <code>-incprivate</code>, the message of the day with <code>-incmotd</code>, notices with <code>-incnotice</code> and other with <code>-incother</code>.</p>
<p>You can see debug info with -debug and verbose output (all messages)<br />
with -verbose. These latter switches just set the $DebugPreference and $VerbosePreference variables to &#8220;Continue&#8221; in the script&#8217;s scope See <a href="http://ps1.soapyfrog.com/2007/01/29/debug-and-verbose-colouring/">Debug and Verbose Colouring</a> for more information on that.</p>
<p><strong>Examples</strong></p>
<p>Here we get chat-irc to monitor the channel #test2 whilst I (millinad) chat to it in a normal IRC chat client.</p>
<pre>PS> chat-irc -coninfo $coninfo -monitor "#test2" | select date,nick,message|ft -wrap

date                         nick                        message
----                         ----                        -------
31/01/2007 14:21:20          millinad                    hello soapybot
31/01/2007 14:21:30          millinad                    nice to see you here
31/01/2007 14:21:38          millinad                    time for you to go now
31/01/2007 14:21:40          millinad                    stopstopstop
</pre>
<p>and in the chat client:</p>
<pre> * soapybot (n=soapybot@*******) has joined #test2
 <millinad> hello soapybot
 <millinad> nice to see you here
 <millinad> time for you to go now
 <millinad> stopstopstop
 * soapybot (n=soapybot@*******) has left #test2
</pre>
<p>Now lets do the same thing again, but with debug switched on and private messages enabled. We&#8217;ll turn off the pipeline formatting.</p>
<pre style='color: #000; background-color: #ccc; '>PS&gt; chat-irc -coninfo $coninfo -monitor &#34;#test2&#34; -incprivate -debug
<span style='color: #888; background-color: #ccc'>DEBUG: Using connection info:</span>
<span style='color: #888; background-color: #ccc'>DEBUG: server: chat.freenode.net</span>
<span style='color: #888; background-color: #ccc'>DEBUG: port: 6667</span>
<span style='color: #888; background-color: #ccc'>DEBUG: user: soapybot</span>
<span style='color: #888; background-color: #ccc'>DEBUG: nick: soapybot</span>
<span style='color: #888; background-color: #ccc'>DEBUG: pwd: ************</span>
<span style='color: #888; background-color: #ccc'>DEBUG: realname: powershell bot using soapyfrog inout-irc.ps1</span>
<span style='color: #888; background-color: #ccc'>DEBUG: hostname: localhost</span>
freenode-connect : soapybot : ☺VERSION☺
<span style='color: #888; background-color: #ccc'>DEBUG: I *may* have joined channel #test2</span>
millinad : #test2 : hello again
millinad : #test2 : i see you received a ctcp message above. pity you don&#39;t understa
nd them.
millinad : #test2 : time to go again
millinad : soapybot : stopstopstop
</pre>
<p>In the last line, I sent soapybot a direct message to stopstopstop rather than to the channel. Without <code>-incprivate</code> this message would not have been output.</p>
<p><strong>How it works</strong></p>
<p>The script connects to the chat server using <code>System.Net.Sockets.TcpClient</code>. Messages are sent using a <code>System.IO.StreamWriter</code> with ASCII encoding. .NET doesn&#8217;t seem to mind of non ASCII chars are translated in this way.</p>
<p>Reading messages is done differently. We can&#8217;t use a <code>System.IO.StreamReader</code>, because <code>ReadLine</code> blocks if there isn&#8217;t a full line available. </p>
<p>We can&#8217;t use asynchronous reading because it&#8217;s quite hard to use scriptblocks as delegates (although that might change in future versions of PowerShell), and threading is a bit of an unknown quantity in PowerShell.</p>
<p>Instead I use the <code>Net.Sockets.NetworkStream</code> with its <code>DataAvailable</code> and <code>ReadByte</code>. This means I can check if data is available, and if not, idle or send messages, then check again. Reading byte by byte makes the code easier to read, and it&#8217;s not too big a performance hit, we&#8217;re bound by the network and the speed of people typing <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Lines are processed in the <code>process-line</code> function where the line is parsed and checked for known numeric responses and commands.</p>
<p>The default handling of a message is in the function <code>_onprivmsg</code> where the message is just formatted and decorated and place into the output pipeline.</p>
<p> <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_idea.gif' alt=':idea:' class='wp-smiley' /> If you wanted to have this bot do something else, you would do it here.</p>
<p><strong>A good chat citizen</strong></p>
<p>This script tries to be a good citizen by throttling it&#8217;s message sending with 1 second delays between messages. This is set with the <code>-throttledelay</code> parameter (milliseconds). The amount of time the script idles when there is no data from the server is 2 seconds, set with the <code>-idledelay</code> parameter.</p>
<p>Even with these values, it&#8217;s still possibly to be killed by a server for flooding. You may want to ask server admin to reduce the flood spec for your bot, or increase the throttledelay.</p>
<p>For example, at chat.freenode.net, piping the output from a directory listing would still cause a flood.</p>
<p>Enjoy <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/31/irc-chat-bot-and-monitor/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Debug and Verbose colouring</title>
		<link>http://ps1.soapyfrog.com/2007/01/29/debug-and-verbose-colouring/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/29/debug-and-verbose-colouring/#comments</comments>
		<pubDate>Mon, 29 Jan 2007 17:59:05 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Hint]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/29/debug-and-verbose-colouring/</guid>
		<description><![CDATA[Over the weekend, I set about writing an IRC chat client/channel monitoring tool in PowerShell (more on that in a day or so) and one of the things I was doing a lot was writing verbose and debug information to the console.
By default, Write-Verbose and Write-Debug cmdlets write nothing to the console, because the the [...]]]></description>
			<content:encoded><![CDATA[<p>Over the weekend, I set about writing an IRC chat client/channel monitoring tool in PowerShell (more on that in a day or so) and one of the things I was doing a lot was writing verbose and debug information to the console.</p>
<p>By default, <code>Write-Verbose</code> and <code>Write-Debug</code> cmdlets write nothing to the console, because the the value of the variables <code>$VerbosePreference</code> and <code>$DebugPreference</code> respectively are &#8220;SilentlyContinue&#8221;.</p>
<p>If you set them both to &#8220;Continue&#8221; the text is written to the console, but both in bright yellow on black (I wonder why?), like this:</p>
<pre style='color: #eeedf0; background-color: #012456; '>PS&gt; $DebugPreference=&#34;continue&#34;
PS&gt; $VerbosePreference=&#34;continue&#34;
PS&gt; write-debug &#34;debug msg&#34;
<span style='color: #ff0; background-color: #000'>DEBUG: debug msg</span>
PS&gt; write-verbose &#34;verbose msg&#34;
<span style='color: #ff0; background-color: #000'>VERBOSE: verbose msg</span>
</pre>
<p>These colours can be changed so you can more easily distinguish between debug and verbose messages, and also not have the real output swamped.</p>
<p><span id="more-51"></span></p>
<p>The trick is to change the values of the colours in <code>$host.privatedata</code>, and   I do this:</p>
<pre>$defbg="darkmagenta"
$deffg="darkyellow"

# normal colours
$r=$host.ui.rawui
$r.BackgroundColor=$defbg
$r.foregroundColor=$deffg

$p=$host.privatedata
# error colours
$p.ErrorBackgroundColor=$defbg
$p.ErrorForegroundColor="red"

# warning colours
$p.WarningBackgroundColor=$defbg
$p.WarningForegroundColor="yellow"

# debug colours
$p.DebugBackgroundColor=$defbg
$p.DebugForegroundColor="darkgray"

# verbose colours
$p.VerboseBackgroundColor=$defbg
$p.VerboseForegroundColor="darkcyan"

# progress colours
$p.ProgressBackgroundColor="darkcyan"
$p.ProgressForegroundColor="yellow"
</pre>
<p>Now, the IRC app I&#8217;m working on, when I run with debug/verbose switched on, yields an output like this:</p>
<pre style='color: #eeedf0; background-color: #012456; font-family: "courier new"; font-size: 9pt; '>PS&gt; test
<span style='color: #888; background-color: #012456'>DEBUG: Using connection info:</span>
<span style='color: #888; background-color: #012456'>DEBUG: port: 6667</span>
<span style='color: #888; background-color: #012456'>DEBUG: nick: soapybot</span>
<span style='color: #888; background-color: #012456'>DEBUG: server: chat.freenode.net</span>
<span style='color: #888; background-color: #012456'>DEBUG: hostname: localhost</span>
<span style='color: #888; background-color: #012456'>DEBUG: user: soapybot</span>
<span style='color: #888; background-color: #012456'>DEBUG: realname: inout-irc as soapybot</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; NICK soapybot</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; USER soapybot localhost chat.freenode.net :inout-irc as soapybot</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> NOTICE AUTH :*** Looking up your hostname...</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> NOTICE AUTH :*** Found your hostname, welcome back</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> NOTICE AUTH :*** Checking ident</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> NOTICE AUTH :*** No identd (auth) response</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 001 soapybot :Welcome to the freenode IRC Network </span>
<span style='color: #088; background-color: #012456'>soapybot</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 002 soapybot :Your host is </span>
<span style='color: #088; background-color: #012456'>brown.freenode.net[brown.freenode.net/6667], running version hyperion-1.0.2b</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> NOTICE soapybot :*** Your host is </span>
<span style='color: #088; background-color: #012456'>brown.freenode.net[brown.freenode.net/6667], running version hyperion-1.0.2b</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 003 soapybot :This server was created Fri Dec 22 </span>
<span style='color: #088; background-color: #012456'>00:07:52 UTC 2006</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 004 soapybot brown.freenode.net hyperion-1.0.2b </span>
<span style='color: #088; background-color: #012456'>aAbBcCdDeEfFGhHiIjkKlLmMnNopPQrRsStTuUvVwWxXyYzZ01234569*@ bcdefFhiIklmnoPqstv</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 005 soapybot IRCD=dancer CAPAB CHANTYPES=# EXCEPTS INVEX</span>
<span style='color: #088; background-color: #012456'> CHANMODES=bdeIq,k,lfJD,cgijLmnPQrRstz CHANLIMIT=#:20 PREFIX=(ov)@+ MAXLIST=bdeI:50 </span>
<span style='color: #088; background-color: #012456'>MODES=4 STATUSMSG=@ KNOCK NICKLEN=16 :are supported by this server</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 005 soapybot SAFELIST CASEMAPPING=ascii CHANNELLEN=30 </span>
<span style='color: #088; background-color: #012456'>TOPICLEN=450 KICKLEN=450 KEYLEN=23 USERLEN=10 HOSTLEN=63 SILENCE=50 :are supported by </span>
<span style='color: #088; background-color: #012456'>this server</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 251 soapybot :There are 18601 listed and 16168 unlisted </span>
<span style='color: #088; background-color: #012456'>users on 24 servers</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 375 soapybot :- brown.freenode.net Message of the Day - </span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- Freenode is a service of Peer-Directed </span>
<span style='color: #088; background-color: #012456'>Projects Center, an</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- IRS 501(c)(3) not-for-profit </span>
<span style='color: #088; background-color: #012456'>organization.  Our yearly</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- fundraiser will begin soon; if you&#39;d </span>
<span style='color: #088; background-color: #012456'>like to donate early,</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- please see </span>
<span style='color: #088; background-color: #012456'>http://freenode.net/pdpc_donations.shtml for more</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- information.  Thank you for using </span>
<span style='color: #088; background-color: #012456'>freenode!</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 372 soapybot :- </span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 376 soapybot :End of /MOTD command.</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; JOIN #test,#test2,#archlinux</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :freenode-connect!freenode@freenode/bot/connect PRIVMSG soapybot :☺VERSION☺</span>
freenode-connect : soapybot : VERSION
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :soapybot!n=soapybot@*********** JOIN :#test</span>
<span style='color: #888; background-color: #012456'>DEBUG: We may have joined channel #test</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 332 soapybot #test :Welcome to #test - This channel is </span>
<span style='color: #088; background-color: #012456'>for testing only. Don&#39;t harass or annoy other users here. Don&#39;t paste senceless crap </span>
<span style='color: #088; background-color: #012456'>here. If you need a response for tests type &#39;#say foobar&#39; or &#39;#moo&#39; - Have a nice time </span>
<span style='color: #088; background-color: #012456'>in here... RIP lilo aka rob levin :&#39;(</span>
<span style='color: #888; background-color: #012456'>DEBUG: We have joined channel #test</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :soapybot!n=soapybot@*************** JOIN :#test2</span>
<span style='color: #888; background-color: #012456'>DEBUG: We may have joined channel #test2</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; PRIVMSG #test2 :hello</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :soapybot!n=soapybot@*************** JOIN :#archlinux</span>
<span style='color: #888; background-color: #012456'>DEBUG: We may have joined channel #archlinux</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :brown.freenode.net 332 soapybot #archlinux :[ Welcome to #archlinux! </span>
<span style='color: #088; background-color: #012456'>(!rules) || main: archlinux.org || forums: bbs.archlinux.org || wiki: wiki.archlinux.org</span>
<span style='color: #088; background-color: #012456'> || bugs: bugs.archlinux.org || AUR: aur.archlinux.org || iso: </span>
<span style='color: #088; background-color: #012456'>ftp://ftp.archlinux.org/other/0.8 ]</span>
<span style='color: #888; background-color: #012456'>DEBUG: We have joined channel #archlinux</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :schnappi!n=joy@debiancenter/user/schnappi PRIVMSG #test :Good after-noon, </span>
<span style='color: #088; background-color: #012456'>soapybot. It&#39;s 17:28h.GMT</span>
schnappi : #test : Good after-noon, soapybot. It&#39;s 17:28h.GMT
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :Danny|!n=Danny@89-172-171-230.adsl.net.t-com.hr PART #archlinux :&#34;So Say We</span>
<span style='color: #088; background-color: #012456'> All.&#34;</span>
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :millinad!n=millinad@*************** PRIVMSG #test2 :hello </span>
<span style='color: #088; background-color: #012456'>soapybot</span>
millinad : #test2 : hello soapybot
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :millinad!n=millinad@*************** PRIVMSG #test2 :go now</span>
millinad : #test2 : go now
<span style='color: #088; background-color: #012456'>VERBOSE: <span>&lt;</span><span>&lt;</span> :millinad!n=millinad@*************** PRIVMSG #test2 :wibble</span>
millinad : #test2 : wibble
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; PART #test2</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; PART #archlinux</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; PART #test</span>
<span style='color: #088; background-color: #012456'>VERBOSE: &gt;&gt; QUIT :bye bye</span>
</pre>
<p>(some of the above has been trimmed for clarity and privacy).</p>
<p>The brighter white output is the normal output from the script, the grey is debug messages and cyan, verbose. It gives me all the output I want, without making it too hard to pick out the real information.</p>
<p>Once I&#8217;m happy that all is well, I can revert the <code>$VerbosePreference</code> and <code>$DebugPreference</code> variables back to &#8220;SilentlyContinue&#8221; and all you get is the default white output.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/29/debug-and-verbose-colouring/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Making functions *really* read-only</title>
		<link>http://ps1.soapyfrog.com/2007/01/26/making-functions-really-read-only/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/26/making-functions-really-read-only/#comments</comments>
		<pubDate>Fri, 26 Jan 2007 10:24:34 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Odd]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/26/making-functions-really-read-only/</guid>
		<description><![CDATA[Over at the excellent PowerShell Team Blog, Bruce Payette wrote about Controlling PowerShell Function (Re)Definition.
However, making a function constant does not prevent it from being shadowed in child scopes. Given that a child scope is created in any script, new function definition or script block, this makes it very unconstant. 

Consider this:
# define a constant [...]]]></description>
			<content:encoded><![CDATA[<p>Over at the excellent PowerShell Team Blog, Bruce Payette wrote about <a href="http://blogs.msdn.com/powershell/archive/2007/01/25/controlling-powershell-function-re-definition.aspx">Controlling PowerShell Function (Re)Definition</a>.</p>
<p>However, making a function <code>constant</code> does not prevent it from being shadowed in child scopes. Given that a child scope is created in any script, new function definition or script block, this makes it very <em>unconstant</em>. </p>
<p><span id="more-49"></span></p>
<p>Consider this:</p>
<pre># define a constant function, one that cannot be replaced
set-item function:/funca -option constant {
  write-host "this is the outer funca"
  # redefine the function in this new scope
  function funca {
    write-host "this is the inner funca"
  }
  # call this new funca
  funca
}

# call the outer one
funca
</pre>
<p>If you run it, you will see that the inner funca is defined and executed. So much for being constant.</p>
<p>You can, however, make it a bit more permanent by adding the <code>allscope</code> option to the outer function, like this:</p>
<pre># define a constant function, one that cannot be replaced
set-item function:/funca -option constant,<strong>allscope</strong> {
  write-host "this is the outer funca"
  # redefine the function in this new scope - this will fail!
  function funca {
    write-host "this is the inner funca"
  }
}

# call the outer one
funca
</pre>
<p>When we run this, we get an error:</p>
<pre style='color: #000; background-color: #eee; '>PS> funcs
this is the outer funca
<span style='color: #f00; background-color: #fff'>Cannot write to function funca because it is read-only or constant.</span>
<span style='color: #f00; background-color: #fff'>At C:/Documents and Settings/adrian/My Documents/proj/ps1/funcs.ps1:5 char:17</span>
<span style='color: #f00; background-color: #fff'>+   function funca  <span><</span><span><</span><span><</span><span><</span> {</span>
</pre>
<p>Why? Because <code>allscope</code> copies the function to all child scopes that are created. The default behaviour, when finding a function (or variable) is to look in the current scope, then the parent, and so on up to <code>global</code>. By automatically copying the constant function to all scopes, you can prevent the function from ever being redefined.</p>
<p>So to make a function as constant as possible, define it with <code>constant,allscope</code> in your <code>$profile</code>.</p>
<p>PS. It appears that you can use scope modifiers with <code>test-path</code>. These two commands do seem to work, although I&#8217;ve not seen any documentation regarding it:</p>
<pre>test-path function:/funca
test-path function:/script:funca
</pre>
<p>However, <code>get-childitem function:</code> only shows one.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/26/making-functions-really-read-only/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Updated get-bufferhtml</title>
		<link>http://ps1.soapyfrog.com/2007/01/25/updated-get-bufferhtml/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/25/updated-get-bufferhtml/#comments</comments>
		<pubDate>Thu, 25 Jan 2007 14:52:11 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Announce]]></category>

		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Utility]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/25/updated-get-bufferhtml/</guid>
		<description><![CDATA[A while back, I posted an article: Console screen grabs in html.
I fixed some bugs and added a couple of new features to the script get-bufferhtml.ps1, and have updated the article with examples.
Enjoy!
]]></description>
			<content:encoded><![CDATA[<p>A while back, I posted an article: <a href="/2007/01/06/console-screen-grabs-in-html/">Console screen grabs in html</a>.</p>
<p>I fixed some bugs and added a couple of new features to the script <a id="p27" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/get-bufferhtmlps1.txt" title="get-bufferhtml.ps1">get-bufferhtml.ps1</a>, and have updated the <a href="/2007/01/06/console-screen-grabs-in-html/">article</a> with examples.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/25/updated-get-bufferhtml/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Webserver and RSH in PowerShell</title>
		<link>http://ps1.soapyfrog.com/2007/01/24/webserver-and-rsh-in-powershell/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/24/webserver-and-rsh-in-powershell/#comments</comments>
		<pubDate>Wed, 24 Jan 2007 12:57:45 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/24/webserver-and-rsh-in-powershell/</guid>
		<description><![CDATA[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&#8217;s a working example with some genuine uses (well useful for me).
I&#8217;ll leave all the security and risk concerns as an exercise for the reader  

What we [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wanted to control a PowerShell session from a web browser or <a href="http://en.wikipedia.org/wiki/CURL">curl/wget</a> on another machine? </p>
<p>Yes? Well it surprisingly simple using PowerShell to script the <code>System.Net.HttpListener</code>. Here&#8217;s a <a id="p46b" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/httpdps1.txt">working example</a> with some genuine uses (well useful for me).</p>
<p>I&#8217;ll leave all the security and risk concerns as an exercise for the reader <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span id="more-47"></span></p>
<p>What we have here is a small PowerShell script, <a id="p46" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/httpdps1.txt">httpd.ps1</a>, 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.</p>
<p>To use it, type this in a PowerShell window: </p>
<pre>./httpd</pre>
<p>This will set the web server listening on <code>http://yourhostname:8888/</code>. You can change this to be something else by supplying a prefix as a parameter, eg:</p>
<pre>./httpd http://192.168.0.28:8888/</pre>
<p>or safer (in case it crashes)</p>
<pre>powershell -command ./httpd http://192.168.0.28:8888/</pre>
<p>This parameter must end in a slash.</p>
<p>You&#8217;ll need to open the appropriate port in your firewall, if you intend to try to use this from a different machine.</p>
<p>Once running (and using that example above) you can enter that url into your web browser, and the response you&#8217;ll get should be something like:</p>
<pre>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</pre>
<p>You can see from this that you need to supply a command. Try this:</p>
<pre>http://192.168.0.28:8888/?cmd=get-process</pre>
<p>What you get back is a process listing for the host machine.</p>
<p>I use this mostly with the command line tool <a href="http://en.wikipedia.org/wiki/CURL">curl</a> to get command output on my Mac, eg:</p>
<pre>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
</pre>
<p>You have to escape the URL for curl, but this executed <code>ps|where {$_.ws -gt 10mb}</code> (all processes with a working set greater than 10mb).</p>
<p>Note that  this script does not show you the output from <code>write-host</code> or any errors, but if you ask for <code>$Error</code> you will get the recent errors returned.</p>
<p>An alternative would be to modify the script to use <a href="/2007/01/06/console-screen-grabs-in-html/">get-bufferhtml</a> to return a full copy of the PowerShell buffer.</p>
<p>Anyways, I learned how easy it is to write a mini web server in .NET and PowerShell, so I&#8217;m happy <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Oh, one last thing. To stop the script, send it a <code>cmd=quit</code>. You could just ctrl+break in the PowerShell window, but I find that causes the whole host to disappear. </p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/24/webserver-and-rsh-in-powershell/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Running pipelines in the background</title>
		<link>http://ps1.soapyfrog.com/2007/01/22/running-pipelines-in-the-background/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/22/running-pipelines-in-the-background/#comments</comments>
		<pubDate>Mon, 22 Jan 2007 14:34:18 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/22/running-pipelines-in-the-background/</guid>
		<description><![CDATA[In the unix world, we&#8217;re used to being able to run the different commands in a pipeline in different threads/processes. This is usually a lot more efficient when the producer/consumer rates vary, and makes use of multiple cores/cpus.
For example, cmd1 &#124; cmd2 will run the two commands in separate processes.
PowerShell doesn&#8217;t do this. Everything runs [...]]]></description>
			<content:encoded><![CDATA[<p>In the unix world, we&#8217;re used to being able to run the different commands in a pipeline in different threads/processes. This is usually a lot more efficient when the producer/consumer rates vary, and makes use of multiple cores/cpus.</p>
<p>For example, <code>cmd1 | cmd2</code> will run the two commands in separate processes.</p>
<p>PowerShell doesn&#8217;t do this. Everything runs in one thread, and pipelined objects are processed in batches, one bit at a time. You can control the batch size with the <code>-outBuffer</code> parameter, but things are still done sequentially, with one command in the pipe being busy whilst all others are sitting idle.</p>
<p>Even the venerable CMD.exe will put these two commands <code>tree | more</code> into separate processes.</p>
<p>This aside, what about simply running an arbitrary command (or scriptblock) in the background whilst doing something else?</p>
<p><span id="more-45"></span></p>
<p>PowerShell doesn&#8217;t have any obvious way to do this, but it is possible with <strong>runspaces</strong>. You can create a new runspace and then invoke a pipeline asynchronously.</p>
<p>Here is an <a id="p44" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/usingrunspacesps1.txt">example script</a>, but lets go through it step by step.</p>
<pre>$rscfg = [management.automation.runspaces.runspaceconfiguration]::Create()
$rs=[management.automation.runspaces.runspacefactory]::CreateRunspace($rscfg)
$rs.Open()</pre>
<p>Here, we create a <code>runspace</code> with a default configuration. There is an overloaded version of <code>CreateRunspace</code> that takes a <code>PSHost</code> object, so we could pass in <code>$host</code>. In this case we just use the default. We then open the <code>runspace</code>.</p>
<pre>$block = {
  $sum=0
  "adding numbers in background!"
  foreach($i in $input) {
    $sum+=$i
    start-sleep 1 # pretent it takes ages to compute this
    "adding number $i"
  }
  "that's it, sum is $sum"
}
$pipe=$rs.CreatePipeline($block)
</pre>
<p>Here we create the scriptblock <code>$block</code> that we want to run in the background and create a pipeline <code>$pipe</code> for it. The block itself simply takes it time adding up numbers passed to it, yielding textual information to the pipe, ending with the result.</p>
<pre>$writer = $pipe.Input
$pipe.InvokeAsync()
</pre>
<p>Here we simply grab hold of the pipe&#8217;s input then invoke it asynchronously.</p>
<pre>$numwritten = $writer.Write(1..5,$true)
$writer.Close()
</pre>
<p>This is where we give the background pipe some data to play with. <code>Write(1..5,$true)</code> means write the numbers 1 through 5 into the pipeline (<code>$true</code> means send the numbers one at a time instead of all at once).</p>
<pre>1..3 | foreach { start-sleep 1; "busy in foreground $_" }
</pre>
<p>The whole purpose of this example is to show how two different things can be done at once, so here we simply spend 3 seconds pretending to be busy <img src='http://ps1.soapyfrog.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<pre>
$reader = $pipe.Output
while (-not $reader.EndOfPipeline) {
  $o = $reader.Read()
  write-host "$o"
}
</pre>
<p>Here we get the output <code>$reader</code> from the pipeline and whilst there is data, read an object and display it.  </p>
<p>We didn&#8217;t have to do it this way; we could have read the whole thing in one go like this: <code>$out = $reader.ReadToEnd()</code>. The latter might be better if the background work produces a single result, but the line-by-line version may suit something with a lot of output. Although we simple do a <code>write-host "$o"</code> here, this could be a lengthy operation that would run whilst the background operation continues to do work.</p>
<pre>$pipe.Error.ReadToEnd()
$pipe.Dispose()
$rs.Close()
</pre>
<p>Finally we consume any error output and clean up.</p>
<p>If you run the <a id="p44" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/usingrunspacesps1.txt">example script</a>, you will see something like this:</p>
<pre>busy in foreground 1
busy in foreground 2
busy in foreground 3
adding numbers in background!
adding number 1
adding number 2
adding number 3
adding number 4
adding number 5
that's it, sum is 15</pre>
<p>This is great, but why is this post categorised as a rant? Well, it&#8217;s very long-winded and in my mind, async job scheduling is something that all shells should do.</p>
<p>It&#8217;s a pity PowerShell doesn&#8217;t let you do something like this:</p>
<pre>{ foo | bar ; wibble}.InvokeAsync()</pre>
<p>or</p>
<pre>invoke-command -async { foo | bar ; wibble }</pre>
<p>You <strong>can</strong> do this, however:</p>
<pre>{ foo | bar ; wibble}.Invoke()</pre>
<p>So how would all this be used? Would it make <a href="/2007/01/02/space-invaders/">space invaders</a> any quicker on a core duo pc? Only a profiler would know.</p>
<p>A single runspace can only have one asynchronous pipeline running and the pipeline cannot be reused. The setup costs are quite high, so you&#8217;d probably have to mess about with a single background pipeline reading work requests and writing them back.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/22/running-pipelines-in-the-background/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Banners</title>
		<link>http://ps1.soapyfrog.com/2007/01/19/banners/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/19/banners/#comments</comments>
		<pubDate>Fri, 19 Jan 2007 14:37:46 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Utility]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/19/banners/</guid>
		<description><![CDATA[In the old days, when you printed something out, you&#8217;d have to wander down to the print room and find your output in a stack of fanfold with the job name printed as a large banner on the top. I miss those days so I wrote a banner script to do this:


It&#8217;s a script, so [...]]]></description>
			<content:encoded><![CDATA[<p>In the old days, when you printed something out, you&#8217;d have to wander down to the print room and find your output in a stack of fanfold with the job name printed as a large banner on the top. I miss those days so I wrote a banner script to do this:</p>
<p><img id="image43" src="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/banner1.gif" alt="banner screenshot" /></p>
<p><span id="more-42"></span></p>
<p>It&#8217;s a script, so execute it directly. It takes a string (or array of strings) as the first argument and two optional parameters, <tt>-fg <em>char</em></tt> to set the foreground character and <tt>-bg <em>char</em></tt> for the background character. The defaults are a solid block and a space. For example:</p>
<pre style='color: #eeedf0; background-color: #012456;'>PS> banner "hello","world" -fg "/"
/   / ///// /     /      ///
/   / /     /     /     /   /
///// ///   /     /     /   /
/   / /     /     /     /   /
/   / ///// ///// /////  ///

/   /  ///  ////  /     ////
/   / /   / /   / /     /   /
/ / / /   / ////  /     /   /
// // /   / /   / /     /   /
/   /  ///  /   / ///// ////

PS>
</pre>
<p><strong>You can download the script here: <a id="p40" href="http://ps1.soapyfrog.com/wp-content/uploads/2007/01/bannerps1.txt">banner.ps1</a>.</strong></p>
<p>Don&#8217;t copy/paste this - save it directly from the above link. It contains formatted text that may get corrupted.</p>
<p>Enjoy!</p>
<p>[Update] The script will also take input from the pipeline so you can do things like:</p>
<p><tt>[enum]::getnames([consolecolor]) | where { $_ -notlike &#8220;dark*&#8221;} | banner -fg &#8220;#&#8221;</tt></p>
<p>to get this:</p>
<pre style='color: #eeedf0; background-color: #012456'>
####  #      ###   ###  #   #
#   # #     #   # #   # #  #
####  #     ##### #     ###
#   # #     #   # #   # #  #
####  ##### #   #  ###  #   #                                                                             

 ###  ####   ###  #   #
#     #   # #   #  # #
#  ## ####  #####   #
#   # #   # #   #   #
 ###  #   # #   #   #                                                                                     

####  #     #   # #####
#   # #     #   # #
####  #     #   # ###
#   # #     #   # #
####  #####  ###  #####                                                                                   

 ###  ####  ##### ##### #   #
#     #   # #     #     ##  #
#  ## ####  ###   ###   # # #
#   # #   # #     #     #  ##
 ###  #   # ##### ##### #   #                                                                             

 ###  #   #  ###  #   #
#   #  # #  #   # ##  #
#       #   ##### # # #
#   #   #   #   # #  ##
 ###    #   #   # #   #                                                                                   

####  ##### ####
#   # #     #   #
####  ###   #   #
#   # #     #   #
#   # ##### ####                                                                                          

#   #  ###   ###  ##### #   # #####  ###
## ## #   # #     #     ##  #   #   #   #
# # # ##### #  ## ###   # # #   #   #####
#   # #   # #   # #     #  ##   #   #   #
#   # #   #  ###  ##### #   #   #   #   #                                                                 

#   # ##### #     #      ###  #   #
 # #  #     #     #     #   # #   #
  #   ###   #     #     #   # # # #
  #   #     #     #     #   # ## ##
  #   ##### ##### #####  ###  #   #                                                                       

#   # #   #  ###  ##### #####
#   # #   #   #     #   #
# # # #####   #     #   ###
## ## #   #   #     #   #
#   # #   #  ###    #   #####                                                                             
</pre>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/19/banners/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Alternate Data Streams</title>
		<link>http://ps1.soapyfrog.com/2007/01/18/alternate-data-streams/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/18/alternate-data-streams/#comments</comments>
		<pubDate>Thu, 18 Jan 2007 11:23:18 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/18/alternate-data-streams/</guid>
		<description><![CDATA[NTFS has the ability to associate multiple data streams (aka forks) to a file. It&#8217;s not very well supported in most Microsoft tools and not very well known, but I use them quite a bit for associating metadata with files.
Unfortunately, PowerShell (or rather .NET) doesn&#8217;t support them very well.

If I open up a  &#8220;Command [...]]]></description>
			<content:encoded><![CDATA[<p>NTFS has the ability to associate multiple <a href="http://support.microsoft.com/kb/105763">data streams</a> (aka forks) to a file. It&#8217;s not very well supported in most Microsoft tools and not very well known, but I use them quite a bit for associating metadata with files.</p>
<p>Unfortunately, PowerShell (or rather .NET) doesn&#8217;t support them very well.</p>
<p><span id="more-38"></span></p>
<p>If I open up a  &#8220;Command Prompt&#8221; window (CMD.EXE), I can do things like this:</p>
<pre style="color: white; background-color: black">CMD>echo Hello world > file.txt

CMD>echo Hello other world > file.txt:other

CMD>more < file.txt
Hello world

CMD>more < file.txt:other
Hello other world</pre>
<p>As you can see, file.txt has two streams, the default one and one named other.</p>
<p>Back in PowerShell:</p>
<pre style='color: #eeedf0; background-color: #012456;'>PS>gc file.txt
Hello world
PS>gc file.txt:other
<span style='color: #f00; background-color: #000'>Get-Content : Cannot find drive. A drive with name 'file.txt' does not exist.</span>
<span style='color: #f00; background-color: #000'>At line:1 char:3</span>
<span style='color: #f00; background-color: #000'>+ gc  < < file.txt:other</span>
</pre>
<p>PowerShell doesn&#8217;t like it. It incorrectly parses the part before the colon as a drive. Even if PowerShell did parse it properly, the underlying .NET bit would fail with <code>System.NotSupportedException: The given path's format is not supported.</code>.</p>
<p>Perhaps Microsoft don&#8217;t want people using ADS any more&#8230; or perhaps they&#8217;re just not sure&#8230; if you <code>Move-Item</code> or <code>Copy-Item</code> the file, the extra stream is moved/copied intact.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/18/alternate-data-streams/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pipe or no pipe?</title>
		<link>http://ps1.soapyfrog.com/2007/01/17/pipe-or-no-pipe/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/17/pipe-or-no-pipe/#comments</comments>
		<pubDate>Wed, 17 Jan 2007 14:50:16 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
		
		<category><![CDATA[Cool]]></category>

		<category><![CDATA[PowerShell]]></category>

		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/17/pipe-or-no-pipe/</guid>
		<description><![CDATA[Many built-in cmdlets take input from the pipe, but alternatively let you specify an input with the -InputObject parameter. An example is the Get-Member cmdlet.
I want to be able to do this with my own functions, but as far as I can tell, there is no built-in mechanism for this for using an specified parameter [...]]]></description>
			<content:encoded><![CDATA[<p>Many built-in cmdlets take input from the pipe, but alternatively let you specify an input with the <code>-InputObject</code> parameter. An example is the <code>Get-Member</code> cmdlet.</p>
<p>I want to be able to do this with my own functions, but as far as I can tell, there is no built-in mechanism for this for using an specified parameter instead of the pipe.</p>
<p>[Updated]</p>
<p><span id="more-37"></span></p>
<p>What I do is this:</p>
<pre># A simple function that multiplies input items by 3
function times3 {
  param($i)
  # this inner function does the actual processing
  function proc($o) {
      $o * 3
  }
  # if -i supplied used instead of std $input
  if ($i) { $input = $i }
  foreach ($o in $input) {
    proc $o
  }
}
</pre>
<p>Normally, you&#8217;d use a function with a <tt>process</tt> block to process each object (<tt>$_</tt>) in the pipeline, but in this case, I iterate over the pipeline&#8217;s <tt>$input</tt> manually. If the <tt>-i</tt> is supplied, <tt>$input</tt> is replaced with its value.</p>
<p>If I run this sequence:</p>
<pre>$debugpreference="Continue"
write-debug "----------- about to call as function"
times3

write-debug "----------- about to pipe 4 numbers in to function"
1..4 | times3

write-debug "----------- about to call as function with -i"
times3 -i (1..4)</pre>
<p>I get this:</p>
<pre style='color: #eeedf0; background-color: #012456;'>PS Documents\\proj\\ps1> ./pipeornot.ps1
<span style='color: #ff0; background-color: #000'>DEBUG: ----------- about to call as function</span>
<span style='color: #ff0; background-color: #000'>DEBUG: ----------- about to pipe 4 numbers in to function</span>
3
6
9
12
<span style='color: #ff0; background-color: #000'>DEBUG: ----------- about to call as function with -in</span>
3
6
9
12
PS Documents\\proj\\ps1> get-bufferhtml > out.html
</pre>
<p>It would be nice if the the manual condition could be avoided by specifying</p>
<pre>param($i=$input)</pre>
<p>but sadly, this does not work.</p>
<p>Maybe in the next version of PowerShell, or perhaps there will be a more specific way of dealing with pipe or no pipe.</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/17/pipe-or-no-pipe/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 2.598 seconds -->
<!-- Cached page served by WP-Cache -->
