<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ps1.soapyfrog.com &#187; Quiz</title>
	<atom:link href="http://ps1.soapyfrog.com/category/quiz/feed/" rel="self" type="application/rss+xml" />
	<link>http://ps1.soapyfrog.com</link>
	<description>doing inappropriate things with powershell</description>
	<lastBuildDate>Sun, 26 Aug 2007 22:01:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<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 [...]]]></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>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hashes and properties</title>
		<link>http://ps1.soapyfrog.com/2007/01/15/hashes-and-properties/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/15/hashes-and-properties/#comments</comments>
		<pubDate>Mon, 15 Jan 2007 16:39:51 +0000</pubDate>
		<dc:creator>adrian</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://ps1.soapyfrog.com/2007/01/15/hashes-and-properties/</guid>
		<description><![CDATA[I really like the way that PowerShell handily formats pipeline objects when displaying them in the console, eg get-childitem in a file system directory returns a collection of file objects and the output is like the old DOS dir command. Additionally, I really like the way that hashes behave like objects with named properties. For [...]]]></description>
			<content:encoded><![CDATA[<p>I really like the way that PowerShell handily formats pipeline objects when displaying them in the console, eg <code>get-childitem</code> in a file system directory returns a collection of file objects and the output is like the old DOS dir command.</p>
<p>Additionally, I really like the way that hashes behave like objects with named properties. For example:</p>
<pre>$a=@{"name"="bob";"age"=42}
$a.name # outputs "bob"
$a.age # outputs 42</pre>
<p>Unfortunately, if you have a list/array of hashes with the same keys, you cannot benefit from this built-in formatting. The output comes out in two columns, keyed <code>Name</code> and <code>Value</code>.</p>
<p>I want a way to have the properties of the hash be the keys and the values be the values associated with those keys.</p>
<p><span id="more-36"></span></p>
<p>Consider the array of hashes created by this code:</p>
<pre>$rnd = new-object Random
$list = @()
1..5 | % {
  $o = @{}
  "keyone","keytwo" | % {
    $o["$_"] = "x$($rnd.next(100))"
  }
  $list += $o
}</pre>
<p>This creates an array of five hashes, each with two keys (keyone and keytwo) with random values.</p>
<p>If we type <code>$list</code> in the console, we get something like this:</p>
<pre>Name                           Value
----                           -----
keyone                         x11
keytwo                         x33
keyone                         x47
keytwo                         x47
keyone                         x72
keytwo                         x57
keyone                         x85
keytwo                         x9
keyone                         x43
keytwo                         x35</pre>
<p>This is not what I want. I want the columns to be keyone and keytwo with the values below.</p>
<p>One way around this is to do something like this (all on one line):</p>
<pre>$list | select-object @{Name="keyone";Expression={$_.keyone}},@{Name="keytwo";Expression={$_.keytwo}}</pre>
<p>Behold! we get what I want:</p>
<pre>keyone                                                      keytwo
------                                                      ------
x72                                                         x71
x18                                                         x6
x59                                                         x60
x37                                                         x39
x63                                                         x10</pre>
<p>Unfortunately, this requires me to know which columns I want in advance, and with more than two columns, it gets rather verbose.</p>
<p>A solution, that works well for me, is to write a function that replaces hashes in the pipe with a custom PowerShell object with added properties&#8230; the cmdlet <code>add-member</code> comes the rescue:</p>
<pre>function convertto-hashobject {
  process {
    if ($_ -is [Collections.IDictionary]) {
      $hash = $_
      $out = new-object object
      foreach ($k in $hash.Keys) {
        $out = add-member -i $out -type "noteproperty" -name "$k" -force -passthru $hash[$k]
      }
      $out
    }
    else {
      $_
    }
  }
}</pre>
<p>Now, regardless of the hash contents, we can do this:</p>
<pre>$list | convertto-hashobject </pre>
<p>to get this:</p>
<pre>keyone                                                      keytwo
------                                                      ------
x72                                                         x71
x18                                                         x6
x59                                                         x60
x37                                                         x39
x63                                                         x10</pre>
<p>Now, this post is tagged as a Quiz, because I&#8217;m sure there is a better way of doing this. Perhaps something blindingly obvious that I missed, or something really cunning.</p>
<p>Let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/15/hashes-and-properties/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making noises</title>
		<link>http://ps1.soapyfrog.com/2007/01/11/making-noises/</link>
		<comments>http://ps1.soapyfrog.com/2007/01/11/making-noises/#comments</comments>
		<pubDate>Thu, 11 Jan 2007 15:54:08 +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/11/making-noises/</guid>
		<description><![CDATA[There are twothree ways I know of to make noises in PowerShell. 1. Simple and most boring: use the internal speaker&#8217;s beep. write-host "`a`a`a" 2. Slightly better, use the .NET console beep. This plays A above middle C for one second. [console]::beep(440,1000) Both of the above are synchronous, ie, the script blocks until the sound [...]]]></description>
			<content:encoded><![CDATA[<p>There are <del>two</del><ins>three</ins> ways I know of to make noises in PowerShell.</p>
<p>1. Simple and most boring: use the internal speaker&#8217;s beep.</p>
<p><code>write-host "`a`a`a"</code></p>
<p>2. Slightly better, use the .NET console beep. This plays A above middle C for one second.</p>
<p><code>[console]::beep(440,1000)</code></p>
<p>Both of the above are synchronous, ie, the script blocks until the sound has finished. <a href="http://wiredupandfiredup.co.uk/">Richy Rich</a> is doing some interesting stuff with <em>runspaces</em> to do this asynchronously.</p>
<p>3. Lastly, you can play wav files. Sadly, only .wav files. No midi, mp3, mpeg4.. at least I couldn&#8217;t find anything in .net 2.</p>
<pre>$file='C:\\WINDOWS\\Media\\Windows XP Startup.wav'
$sp = new-object Media.SoundPlayer ($file)
$sp.Load();
$sp.Play();
1..5 | % {
  echo "la la"
  sleep 1
}
</pre>
<p>This plays the wav asynchronously, so I feel should be used in a future version of <a href="/2007/01/02/space-invaders/">psinvaders</a> to get those authentic sounds.</p>
<p>So anyone know of a way to play midi files asynchronously in PowerShell with only a few lines of code?</p>
]]></content:encoded>
			<wfw:commentRss>http://ps1.soapyfrog.com/2007/01/11/making-noises/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

