<?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>Huddled Masses &#187; Cmdlet</title>
	<atom:link href="http://huddledmasses.org/tag/cmdlet/feed/" rel="self" type="application/rss+xml" />
	<link>http://huddledmasses.org</link>
	<description>You can do more than breathe for free...</description>
	<lastBuildDate>Fri, 27 Apr 2012 05:42:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<cloud domain='huddledmasses.org' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
		<item>
		<title>What&#8217;s the desired behavior of inputObject?</title>
		<link>http://huddledmasses.org/whats-the-desired-behavior-of-inputobject/</link>
		<comments>http://huddledmasses.org/whats-the-desired-behavior-of-inputobject/#comments</comments>
		<pubDate>Sat, 22 Dec 2007 22:59:00 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Behavior]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Cmdlet]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Documentation]]></category>
		<category><![CDATA[Expectations]]></category>
		<category><![CDATA[Pipeline]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Users]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/whats-the-desired-behavior-of-inputobject/</guid>
		<description><![CDATA[In response to Kirk Munro’s comment on my Writing Cmdlets for the PowerShell Pipeline post: You know, I’ve looked at your articles about cmdlets/functions in the pipeline and I feel you’re missing something. The purpose of the InputObject parameter is to pass in a collection as a single object. This is as opposed to using [...]]]></description>
			<content:encoded><![CDATA[	<p>In response to Kirk Munro’s <a href="http://huddledmasses.org/writing-cmdlets-for-the-powershell-pipeline/feed/">comment</a> on my <a href="http://huddledmasses.org/writing-cmdlets-for-the-powershell-pipeline/">Writing Cmdlets for the PowerShell Pipeline</a> post:</p>

	<blockquote>
		<p>You know, I’ve looked at your articles about cmdlets/functions in the pipeline and I feel you’re missing something. The purpose of the InputObject parameter is to pass in a collection as a single object. This is as opposed to using the pipeline where a collection is passed along the pipeline one item at a time. There are cases where you want to pass in a collection as a collection.</p>
	</blockquote>

	<p>Quite simply, I disagree.  The documentation for these parameters says quite clearly that inputObject “Specifies an object or objects to input to the cmdlet.” This clearly means that I should be able to pass multiple objects, <strong>and have them treated as multiple objects</strong>, not as a single array object.</p>

	<blockquote>
		<p>If you look at your example (Select -First 3 -Unique -InputObject $a), this does in fact work. It receives one object, an array. It then selects the first 3 objects, but there is only 1 so that is moot. And lastly it selects unique objects, but again there is only 1 so that is moot as well and finally the object is output using the default formatter. In this case the default formatter is showing the contents of the array.</p>
	</blockquote>

	<p>In this example, <code>Select-Object</code> has no reason to take a <strong>single object</strong> as an input object, at all.  The only time that it would be useful for Select-Object to take a single inputObject would be in combination with the <code>property</code> parameters. In fact, if you want to Select-Object from an array to get the first of last n objects, or to get a set of unique objects, you <em>have to pass the objects in via the pipeline</em> &#8212; there&#8217;s no other way to make it select from an array. If that was indeed the intent, it should have been written as a <strong>separate ParameterSet</strong>, and <em>the documentation should be changed</em> to reflect that only a single object can be passed in, and that you can&#8217;t use the inputObject parameter with the <code>first</code>, <code>last</code>, or <code>unique</code> parameters at all. That’s worse than useless, it’s misleading and confusing.</p>

	<p>Kirk is absolutely right that if you assume that the InputObject argument is only allowed to take a single object, then the behavior is correct – but it’s not logical.  In fact, the behavior you see in the output of this command is so useless as to be a bug – even if the documentation did not say the parameter accepts multiple objects as input:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #0066cc; font-style: italic;">Select-<span style="font-style: normal;">Object</span></span> <span style="color: #000066;">-input</span> <span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">5</span>,<span style="color: #cc66cc;">6</span>,<span style="color: #cc66cc;">4</span>,<span style="color: #cc66cc;">8</span> <span style="color: #000066;">-first</span> <span style="color: #cc66cc;">2</span> <span style="color: #000066;">-unique</span><br />
<span style="color: #cc66cc;">4</span><br />
<span style="color: #cc66cc;">5</span><br />
<span style="color: #cc66cc;">6</span><br />
<span style="color: #cc66cc;">4</span><br />
<span style="color: #cc66cc;">8</span></div>

	<h3>I know that that’s the way the built-in cmdlets work.</h3>

	<p>But quite frankly, just because someone important wrote something useless is no reason to emulate the behavior.  The inputObject parameter IS the same parameter which pipeline objects go into.  There’s no logical explanation for us to get different results when we pass an array in via the parameter by name instead of via pipeline: the PowerShell pipeline passing the things in the pipeline into the –inputObject parameter … it’s not using some mystical variable like it does in script functions.</p>

	<p>Of course, we all know the powershell pipeline unwraps arrays &#8212; that’s convenient, and we can work around it when we really want to pass an array in:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
PS<span style="color: #66cc66;">&gt;</span> @<span style="color: #333;">&#40;</span><span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">int</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span>@<span style="color: #333;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">4</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span> <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;Hi: $_&quot;</span> <span style="color: #333;">&#125;</span> <span style="color: #666666; font-style: italic;"># typecast and wrapped isn’t enough...</span><br />
Hi: <span style="color: #cc66cc;">1</span><br />
Hi: <span style="color: #cc66cc;">2</span><br />
Hi: <span style="color: #cc66cc;">3</span><br />
Hi: <span style="color: #cc66cc;">4</span><br />
<br />
PS<span style="color: #66cc66;">&gt;</span> @<span style="color: #333;">&#40;</span>,<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">int</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span>@<span style="color: #333;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">4</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span> <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;Hi: $_&quot;</span> <span style="color: #333;">&#125;</span> <span style="color: #666666; font-style: italic;"># put it as a member of another array</span><br />
Hi: <span style="color: #cc66cc;">1</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">3</span> <span style="color: #cc66cc;">4</span><br />
<br />
PS<span style="color: #66cc66;">&gt;</span> @<span style="color: #333;">&#40;</span>,@<span style="color: #333;">&#40;</span>,<span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">int</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span>@<span style="color: #333;">&#40;</span><span style="color: #cc66cc;">1</span>,<span style="color: #cc66cc;">2</span>,<span style="color: #cc66cc;">3</span>,<span style="color: #cc66cc;">4</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">%</span> <span style="color: #333;">&#123;</span> <span style="color: #009900;">&quot;Hi: $_&quot;</span> <span style="color: #333;">&#125;</span> &nbsp;<span style="color: #666666; font-style: italic;"># go too deep and “stuff” happens.</span><br />
Hi: System.<span style="color: #003366;">Int32</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span></div>

	<blockquote>
		<p>My point in all of this is that InputObject is actually a very useful parameter, because there are cases where you really want to pass a collection as a collection into a cmdlet and then do something with it. By making InputObject instead split the collection passed in and pipeline it through, you’re forcing users to wrap collections in an array just to get them passed in as a collection, and personally I don’t feel they should have to do that.</p>
	</blockquote>

	<p>While it’s true that passing in an array is sometimes desirable that’s <strong>not</strong> the reason the parameter exists, and I don’t believe it should be the default behavior here. It should be just as easy for me to use the cmdlet with the inputObject parameter directly as it is to input them via the pipeline.  If I put in unwrapping for the inputObject parameter, you can work around it in the same way I did in the examples above. Incidentally, I think <em>*PowerShell* should unwrap arrays to <strong>ValueFromPipeline</strong> parameters regardless of whether they’re on the pipeline</em>, but I recognize it’s probably too late for that.</p>

	<p>Basically, this is my argument: If inputObject unwraps arrays, the syntax for passing an array by wrapping it in @(,$array) is simple, for those <em>rare</em> occasions when that’s actually what you want. But if it does not unwrap arrays, you’re <strong>forced</strong> to call it via a separate pipeline, because unwrapping the array and passing it in one at a time in a foreach loop will almost certainly not do the same thing, and this is much uglier &#8212; and not compatible with use within the pipeline, particularly if you need to pass the pipeline output into a different parameter.</p>

	<p>I guess my final word would be to agree with Kirk that “InputObject … isn’t documented clearly enough” … in fact, it’s clearly <strong>behaving incorrectly according to the documentation</strong>, and that’s why I originally proposed to unwrap the inputObject parameter when it’s passed as a parameter: to make it work the way the documentation suggests it would,  which seems to me to be a better way than the way it actually works.</p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/whats-the-desired-behavior-of-inputobject/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Converting HTML to XML in PowerShell</title>
		<link>http://huddledmasses.org/converting-html-to-xml-in-powershell/</link>
		<comments>http://huddledmasses.org/converting-html-to-xml-in-powershell/#comments</comments>
		<pubDate>Fri, 16 Nov 2007 21:40:32 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Cmdlet]]></category>
		<category><![CDATA[Converting]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Html]]></category>
		<category><![CDATA[Parsing]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Xml]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/converting-html-to-xml-in-powershell/</guid>
		<description><![CDATA[I&#8217;ll write up more information later, but a couple people have asked for this in #PowerShell on irc.freenode.net, and I had it already written, so here you go &#8230; my ConvertFrom-Html cmdlet (in a Huddled.HtmlSnapin). It converts HTML to valid xml using the SGML Parser which was available on GotDotNet years ago. It only works [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ll write up more information later, but a couple people have asked for this in #PowerShell on irc.freenode.net, and I had it already written, so here you go &#8230; my ConvertFrom-Html cmdlet (in a Huddled.HtmlSnapin). It converts <span class="caps">HTML</span> to valid xml using the <span class="caps">SGML</span> Parser which was available on GotDotNet years ago. It only works with files (doesn&#8217;t do <span class="caps">URL</span> downloads yet). Use it like this:</p>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033; font-weight: bold;">$url</span> <span style="color: #66cc66;">=</span> <span style="color: #009900;">&quot;http://huddledmasses.org/&quot;</span><br />
<span style="color: #660033; font-weight: bold;">$file</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">Join-<span style="font-style: normal;">Path</span></span> <span style="color: #660033; font-weight: bold;">$pwd</span> <span style="color: #009900;">&quot;HuddledMasses.html&quot;</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$client</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">new-<span style="font-style: normal;">object</span></span> System.<span style="color: #003366;">Net</span>.<span style="color: #003366;">WebClient</span><br />
<span style="color: #660033; font-weight: bold;">$client</span>.<span style="color: #003366;">DownloadFile</span><span style="color: #333;">&#40;</span> <span style="color: #660033; font-weight: bold;">$url</span>, <span style="color: #660033; font-weight: bold;">$file</span> <span style="color: #333;">&#41;</span> <span style="color: #666666; font-style: italic;">#NOTE: You need to use a full path here, not relative</span><br />
<br />
<span style="color: #660033; font-weight: bold;">$xml</span> <span style="color: #66cc66;">=</span> <span style="color: #0066cc; font-style: italic;">ConvertFrom-<span style="font-style: normal;">Html</span></span> <span style="color: #660033; font-weight: bold;">$file</span><br />
<br />
<span style="color: #666666; font-style: italic;"># Or even</span><br />
<span style="color: #333;">&#40;</span><span style="color: #0066cc; font-style: italic;">ConvertFrom-<span style="font-style: normal;">Html</span></span> <span style="color: #660033; font-weight: bold;">$file</span><span style="color: #333;">&#41;</span>.<span style="color: #003366;">Save</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$file</span><span style="color: #333;">&#41;</span></div>

	<p>The source code to my plugin may be considered public domain, and is included in <a href="http://HuddledMasses.org/wordpress/wp-content/uploads/2007/11/huddledhtmlsnapin.zip">the Huddled <span class="caps">HTML</span> SnapIn Zip</a>.  </p>

	<p><del>However, the SgmlReader library is a Microsoft Sample which is licensed under <a href="http://dev.live.com/sampleseula.aspx">the old MS Samples license</a> which doesn&#8217;t allow reuse with viral open source software. I&#8217;ve seen some work being done on an <a href="http://www.codeplex.com/htmlagilitypack">HtmlAgilityPack</a> on CodePlex (using a Creative Commons <a href="http://www.codeplex.com/htmlagilitypack/Project/License.aspx"><span class="caps">ASA</span> license</a>) but I have not really looked at it except to see that it has a several active issues related to entity encoding and dropping malformed tags which I haven&#8217;t encountered in SgmlReader &#8230;</del></p>

	<p>The <a href="http://code.msdn.microsoft.com/SgmlReader">SGMLReader</a> library has been re-released on <a href="http://code.msdn.microsoft.com/"><span class="caps">MSDN</span> Code Gallery</a> under an Ms-PL license, and all is well with the world.  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=':D' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/converting-html-to-xml-in-powershell/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PowerShell 2.0 CTP &#8211; Script Cmdlets</title>
		<link>http://huddledmasses.org/powershell-20-ctp-script-cmdlets/</link>
		<comments>http://huddledmasses.org/powershell-20-ctp-script-cmdlets/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 22:09:57 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Alpha]]></category>
		<category><![CDATA[Beta]]></category>
		<category><![CDATA[Cmdlet]]></category>
		<category><![CDATA[CTP]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Pipeline]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/powershell-20-ctp-script-cmdlets/</guid>
		<description><![CDATA[Well, the first alpha CTP release of PowerShell 2.0 is out, and there&#8217;s a lot of new stuff in it &#8230; but I won&#8217;t repeat the list from the PowerShell blog, because I&#8217;m sure you&#8217;ve seen it five or six times already. Instead, lets just skip straight to talking about one of the features we&#8217;ve [...]]]></description>
			<content:encoded><![CDATA[	<p>Well, the first <a href="http://blogs.msdn.com/powershell/archive/2007/11/06/what-s-new-in-ctp-of-powershell-2-0.aspx"><del>alpha</del> <span class="caps">CTP</span> release of PowerShell 2.0</a> is out, and there&#8217;s a lot of new stuff in it &#8230; but I won&#8217;t repeat the list from the PowerShell blog, because I&#8217;m sure you&#8217;ve seen it five or six times already. Instead, lets just skip straight to talking about one of the features we&#8217;ve been hearing about the longest: in PowerShell 2, you can create Cmdlets in script &#8230; bringing nearly full parity between  whats possible in a C# cmdlet and what&#8217;s possible in script.</p>

	<p>There are a few caveats still (Parameter Sets aren&#8217;t working yet, and neither is help, really), and a few surprises &#8230; there&#8217;s a few downsides to PowerShell script vs C# ... but in this particular context one thing that stands out is that in C# the <code>BeginProcessing</code>, <code>ProcessRecord</code>, and <code>EndProcessing</code> blocks are actually methods which can call each other, and as demonstrated in my <a href="/writing-cmdlets-for-the-powershell-pipeline/">tutorial for writing cmdlets that work in the pipeline</a>, they can be recursive &#8212; without getting duplicate variables.  </p>

	<h4>A sample Script Cmdlet</h4>

	<p>In the interests of being the first to publish an interesting script cmdlet  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=';)' class='wp-smiley' />  and to continue my recent trend of talking about writing for the PowerShell pipeline, I&#8217;ve merged the logic of my <a href="/writing-better-script-functions-for-the-powershell-pipeline/">script function</a> and my <a href="/writing-cmdlets-for-the-powershell-pipeline/">pipeline cmdlet</a> into a <a href="/wordpress/wp-content/uploads/2007/11/test-pipelinev2.ps1">single sample script cmdlet for PowerShell 2.0</a> and it works great!</p>

	<p>A few observations from the process, in no particular order:</p>

	<ul>
		<li>If you recursively call your cmdlet from within itself, you have to test for parameters using the new <code>$CommandLineParameters.ContainsKey</code> because parameter variables keep their values through recursion if you don&#8217;t explicitly pass a value.</li>
		<li><code>$CommandLineParameters.ContainsKey</code> works differently in the <code>Begin</code> block where it will return <code>$false</code> for arguments which will get their values from the pipeline, than in the <code>Process</code> block where it will treat values which were passed as <code>CommandLineParameters</code> the same as those which were passed via the pipeline.</li>
		<li>If you want to see how your function behaves in a pipeline, you should make sure to test it at different points in the pipeline: at the front, in the middle, and at the end.</li>
		<li>Cmdlets are functions: they show up in the Function provider.</li>
		<li>Cmdlets are functions: they have to be dot-sourced before you can call them.</li>
		<li>Cmdlets are not functions: they are a single command <code>Cmdlet</code> which takes a name (which <strong>must</strong> have a &#8211; in it) and a couple of other parameters followed by a function script block.</li>
	</ul>
	<ul>
		<li>When you recurse by executing &#038;($MyInvocation.InvocationName), that second invocation has an InvocationName of &#8220;&#038;&#8221; ... so you can&#8217;t go any further (this might be a good thing, if you want to stop recursion at one level no matter what. If you want to go further, you need to put your commands into a string, and use <code>Invoke-Expression</code>.</li>
	</ul>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;">#requires -version 2.0</span><br />
<span style="color: #666666; font-style: italic;">###################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">## A Template for Script Cmdlets which can _also_ be executed in the pipeline ....</span><br />
<span style="color: #666666; font-style: italic;">## &nbsp; by Joel Bennett, in hopes it will help...</span><br />
<span style="color: #666666; font-style: italic;">## Version History</span><br />
<span style="color: #666666; font-style: italic;">## v1.0 - First public release (after over 9 different versions in my various other functions)</span><br />
<span style="color: #666666; font-style: italic;">## v1.2 - Show the use of Write-Output, and change &quot;return&quot; in the BEGIN to &quot;Write-Output&quot; to avoid</span><br />
<span style="color: #666666; font-style: italic;">## &nbsp; &nbsp; &nbsp;the pooling of the output from the process block when it's invoked as a function.</span><br />
<span style="color: #666666; font-style: italic;">## v1.3 - Switched back to &quot;break&quot; instead of &quot;return&quot; so that if you pass via the pipeline AND via</span><br />
<span style="color: #666666; font-style: italic;">## &nbsp; &nbsp; &nbsp;the inputObject, only the inputObject gets process (this is how cmdlets behave).</span><br />
<span style="color: #666666; font-style: italic;">## &nbsp; &nbsp; &nbsp;- Cleaned up the comments, and removed the confusing alternate method and $args handling</span><br />
<span style="color: #666666; font-style: italic;">##</span><br />
<span style="color: #666666; font-style: italic;">## v2.0 - First Version as a Script Cmdlet. </span><br />
<span style="color: #666666; font-style: italic;">## &nbsp; &nbsp; &nbsp;This is much easier with support for [ValueFromPipeline] and [ValueFromPipelineByName] </span><br />
<span style="color: #666666; font-style: italic;">##</span><br />
<span style="color: #666666; font-style: italic;">###################################################################################################</span><br />
Cmdlet <span style="color: #0066cc; font-style: italic;">Test-<span style="font-style: normal;">PipelineV2</span></span> <span style="color: #000066;">-ConfirmImpact</span> low <span style="color: #000066;">-snapin</span> Huddled.<span style="color: #003366;">Tests</span><br />
<span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">Param</span> <span style="color: #333;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Position<span style="color: #333;">&#40;</span><span style="color: #cc66cc;">0</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>ConsoleColor<span style="color: #333;">&#93;</span></span> <span style="color: #660033; font-weight: bold;">$Color</span>,<br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#91;</span>Position<span style="color: #333;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#93;</span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>Mandatory<span style="color: #333;">&#93;</span></span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span>ValueFromPipeline<span style="color: #333;">&#93;</span></span> <span style="color: #003366; font-weight: bold;"><span style="color: #333;">&#91;</span><span style="color: #003366; font-weight: bold;">String</span><span style="color: #333;">&#91;</span><span style="color: #333;">&#93;</span><span style="color: #333;">&#93;</span></span> <span style="color: #660033; font-weight: bold;">$InputObject</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">BEGIN</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$CommandLineParameters</span>.<span style="color: #003366;">ContainsKey</span><span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;InputObject&quot;</span><span style="color: #333;">&#41;</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Don't do anything here, because we're about to get re-invoked...</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$FromArgs</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$true</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Normal &quot;run-once&quot; BEGIN processing</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #660033; font-weight: bold;">$FromArgs</span> <span style="color: #66cc66;">=</span> <span style="color: #660033; font-weight: bold;">$false</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;Begin $Color&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">PROCESS</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># We no longer have to test for $_ or even to see if the [ValueFromPipeline] param is set</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># It *HAS* to be set, because it's a [Mandatory] parameter :)</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$FromArgs</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Don't do anything here except re-invoke ourselves.</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #660033; font-weight: bold;">$InputObject</span> <span style="color: #66cc66;">|</span> <span style="color: #66cc66;">&amp;</span><span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$MyInvocation</span>.<span style="color: #003366;">InvocationName</span><span style="color: #333;">&#41;</span> <span style="color: #660033; font-weight: bold;">$Color</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Normal Pipeline-friendly per-item processing</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Host</span></span> <span style="color: #009900;">&quot;Process: $InputObject&quot;</span> <span style="color: #000066;">-Fore</span> <span style="color: #660033; font-weight: bold;">$Color</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## You should make a practice of explicitly calling Write-Output on things</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;">## That's how you emit them into the pipeline instead of just printing them</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Output</span></span> <span style="color: #660033; font-weight: bold;">$InputObject</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #666699; font-weight: bold;">END</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #666699; font-weight: bold;">if</span> <span style="color: #333;">&#40;</span><span style="color: #660033; font-weight: bold;">$FromArgs</span><span style="color: #333;">&#41;</span> <span style="color: #333;">&#123;</span> &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Don't do anything here ... it just confuses things</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span> <span style="color: #666699; font-weight: bold;">else</span> <span style="color: #333;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># Normal &quot;run-once&quot; END processing</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0066cc; font-style: italic;">Write-<span style="font-style: normal;">Verbose</span></span> <span style="color: #009900;">&quot;End $Color&quot;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #333;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #333;">&#125;</span><br />
<span style="color: #333;">&#125;</span><br />
&nbsp;</div>

	<h4>A test case</h4>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #666666; font-style: italic;">## Test Script:</span><br />
<span style="color: #666666; font-style: italic;">##</span><br />
<span style="color: #666666; font-style: italic;">## &quot;a&quot;,&quot;b&quot;,&quot;c&quot; | Test-PipelineV2 &quot;Cyan&quot; -verbose</span><br />
<span style="color: #666666; font-style: italic;">## @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;) | Test-PipelineV2 &quot;Cyan&quot; -verbose</span><br />
<span style="color: #666666; font-style: italic;">## Test-PipelineV2 &quot;Cyan&quot; @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;) -verbose </span><br />
<span style="color: #666666; font-style: italic;">## </span><br />
<span style="color: #666666; font-style: italic;">## &quot;a&quot;,&quot;b&quot;,&quot;c&quot; | Test-PipelineV2 &quot;Cyan&quot; -verbose | Test-PipelineV2 &quot;Green&quot; -verbose</span><br />
<span style="color: #666666; font-style: italic;">## @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;) | Test-PipelineV2 &quot;Cyan&quot; -verbose | Test-PipelineV2 &quot;Green&quot; -verbose</span><br />
<span style="color: #666666; font-style: italic;">## Test-PipelineV2 &quot;Cyan&quot; @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;) -verbose &nbsp;| Test-PipelineV2 &quot;Green&quot; -verbose</span><br />
<span style="color: #666666; font-style: italic;">###################################################################################################</span><br />
<span style="color: #666666; font-style: italic;">## Expected Output (sorry, no color here...)</span><br />
<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Green<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Green<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Green<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Green<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Green<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">Begin</span> Cyan<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: a<br />
a<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: b<br />
b<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
<span style="color: #666699; font-weight: bold;">Process</span>: c<br />
c<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Cyan<br />
VERBOSE: <span style="color: #666699; font-weight: bold;">End</span> Green</div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/powershell-20-ctp-script-cmdlets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Writing Cmdlets for the PowerShell Pipeline</title>
		<link>http://huddledmasses.org/writing-cmdlets-for-the-powershell-pipeline/</link>
		<comments>http://huddledmasses.org/writing-cmdlets-for-the-powershell-pipeline/#comments</comments>
		<pubDate>Tue, 06 Nov 2007 05:25:57 +0000</pubDate>
		<dc:creator>Joel 'Jaykul' Bennett</dc:creator>
				<category><![CDATA[Huddled]]></category>
		<category><![CDATA[Cmdlet]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[My Software]]></category>
		<category><![CDATA[Pipeline]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[SourceCode]]></category>

		<guid isPermaLink="false">http://HuddledMasses.org/writing-cmdlets-for-the-powershell-pipeline/</guid>
		<description><![CDATA[In a continuation of what is, sadly, becoming a series on how the PowerShell Pipeline works &#8230; Karl Prosser brought to my attention that certain powershell commands which have an -InputObject parameter don&#8217;t actually work when you pass something into it &#8230; so I thought I should create a cmdlet to show you how to [...]]]></description>
			<content:encoded><![CDATA[	<p>In a continuation of what is, <em>sadly</em>, becoming a series on how the <a href="/tag/Pipeline">PowerShell Pipeline</a> works &#8230; <a href="http://powershelllive.com/members/karl.aspx">Karl Prosser</a> brought to my attention that certain powershell commands which have an -InputObject parameter don&#8217;t actually work when you pass something into it &#8230; so I thought I should create a cmdlet to show you how to correctly handle the <code>InputObject</code> parameter with the <code>ValueFromPipeline</code> set so you can pass the input in either way.  </p>

	<h4>To demonstrate the problem, try this:</h4>

	<div class="posh code posh" style="font-family:monospace;"><br />
<span style="color: #660033; font-weight: bold;">$a</span> <span style="color: #66cc66;">=</span> @<span style="color: #333;">&#40;</span><span style="color: #009900;">&quot;A&quot;</span>,<span style="color: #009900;">&quot;B&quot;</span>,<span style="color: #009900;">&quot;A&quot;</span>,<span style="color: #009900;">&quot;C&quot;</span><span style="color: #333;">&#41;</span><br />
<span style="color: #660033; font-weight: bold;">$a</span> <span style="color: #66cc66;">|</span> <span style="color: #660033;">Select</span> <span style="color: #000066;">-First</span> <span style="color: #cc66cc;">3</span> <span style="color: #000066;">-Unique</span><br />
<span style="color: #660033;">Select</span> <span style="color: #000066;">-First</span> <span style="color: #cc66cc;">3</span> <span style="color: #000066;">-Unique</span> <span style="color: #000066;">-InputObject</span> <span style="color: #660033; font-weight: bold;">$a</span> </div>

	<p>This should expose two weirdnesses about how the <code>Select-Object</code> cmdlet works: </p>

	<ol>
		<li>The -First parameter affects the input before the -Unique parameter does.</li>
	</ol>
	<ol>
		<li>When you pass the input in via -InputObject, the whole array is treated as a single object, and the command basically doesn&#8217;t do anything.</li>
	</ol>

	<p>The big problem with this behavior is that there&#8217;s essentially no hint that you&#8217;ve done something wrong &#8212; there&#8217;s actually no way to make Select-Object work properly <strong>except</strong> by passing the objects in via the pipeline.  The bigger problem is that it would have been simple for the Microsoft team to catch this and alert you, but they didn&#8217;t &#8212; so you probably won&#8217;t even notice there&#8217;s a problem until you run it on a trivial data set like my example.  The even <strong>bigger problem</strong> is that it doesn&#8217;t just affect Select-Object (try it with Where-Object, just for instance). <span id="more-458"></span></p>

	<h4>The simplest fix</h4>

	<p>When this came up in the #PowerShell <span class="caps">IRC</span> channel <a href="http://nivot.org">Oisin</a> initially defended this as an unavoidable side effect of the way the cmdlet system works. However, after playing with the idea for a bit, we found it&#8217;s actually trivial to stop, although I found it hard to explain without actually <a href="/wordpress/wp-content/uploads/2007/11/testpipelinecommand1.cs">demonstrating an alternative</a>. The simplest possible alternative is just to throw an exception if the value is passed in as an argument instead of via the pipeline. That would preserve the same level of functionality you have now &#8212; but cause an error in those cases where it wouldn&#8217;t work anyway.</p>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> BeginProcessing<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>_input <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">throw</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> ArgumentException<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;You must pass InputObject via the pipeline!&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp;<span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">BeginProcessing</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
<span style="color: #000000;">&#125;</span></div>

	<h4>A better way to handle input</h4>

	<p>Of course, you can do better than that  <img src='http://huddledmasses.org/wordpress/wp-includes/' alt=';)' class='wp-smiley' /> .  So, I hereby present the first version of my <a href="/wordpress/wp-content/uploads/2007/11/testpipelinecommand2.cs">PowerShell Pipeline Template Cmdlet</a>.  It&#8217;s pretty simple really (once you get past all the cmdlet overhead): basically, you check in the <code>BeginProcess()</code> method to see if the <code>InputObject</code> parameter has been set, and set an alternate private variable. Then, in the <code>ProcessRecord()</code> method, we have two alternate computation paths: the normal path, and a second path for when the collection is passed in as an argument.  In that case, you recurse and call the ProcessRecord method once for each item in the collection.</p>

	<p>I&#8217;m sure some of you will have some improvements you can make, feel free to continue the development on the PowerShell Central <a href="http://powershellcentral.com/scripts/43">scripts page</a> or by sending feedback in the form below, but for now, here&#8217;s <a href="/wordpress/wp-content/uploads/2007/11/testpipelinecmdlet.7z">the Test-Pipeline Cmdlet Binary</a> and the <a href="/wordpress/wp-content/uploads/2007/11/testpipelinecommand2.cs">source code</a>.</p>

	<h4>The Code</h4>

	<div class="csharp code csharp" style="font-family:monospace;"><br />
<span style="color: #008080; font-style: italic;">// An improvement! Now we accept a single object (like Select-Object does)</span><br />
<span style="color: #008080; font-style: italic;">// But, unlike Select-Object, if an array is passed into the argument -InputObject </span><br />
<span style="color: #008080; font-style: italic;">// we still manage to process each item in the array, as we would in the pipeline</span><br />
<span style="color: #008080; font-style: italic;">//</span><br />
<span style="color: #008080; font-style: italic;">// Try it out: &nbsp; &quot;a&quot;,&quot;b&quot;,&quot;c&quot;| Test-Pipeline -verbose</span><br />
<span style="color: #008080; font-style: italic;">// Versus this: &nbsp;Test-Pipeline -verbose -input @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;)</span><br />
<span style="color: #008080; font-style: italic;">//</span><br />
<span style="color: #008080; font-style: italic;">// If you don't set the -verbose flag, you shouldn't be able to tell them apart</span><br />
<span style="color: #008080; font-style: italic;">// The first way, the &quot;1&quot; invocation hits ProcessRecord for &quot;a&quot; </span><br />
<span style="color: #008080; font-style: italic;">// ... before the &quot;2&quot; invocation hits BeginProcessing()</span><br />
<span style="color: #008080; font-style: italic;">//</span><br />
<span style="color: #008080; font-style: italic;">// Version History</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp;1.0 Just throws an exception</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp;2.0 Finds a way to enumerate ProcessRecord from BeginProcessing</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp;There is still a slight difference, which you can see if you test these:</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Test-Pipeline 1 -input @(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;) -verbose | Test-Pipeline 2 -verbose</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&quot;a&quot;,&quot;b&quot;,&quot;c&quot; | Test-Pipeline 1 -verbose | Test-Pipeline 2 -verbose</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp;2.3 Recursed from inside ProcessRecord instead of BeginProcessing</span><br />
<span style="color: #008080; font-style: italic;">// &nbsp; &nbsp; &nbsp; &nbsp;Makes the execution look identical in the test case from 2.0</span><br />
<span style="color: #008080; font-style: italic;">////////////////////////////////////////////////////////////////////////////////</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Collections.Generic</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Text</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Management.Automation</span><span style="color: #008000;">;</span><br />
<span style="color: #0600FF;">using</span> <span style="color: #008080;">System.Collections</span><span style="color: #008000;">;</span><br />
<br />
<span style="color: #0600FF;">namespace</span> Huddled.<span style="color: #0000FF;">TestSnapin</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#91;</span>Cmdlet<span style="color: #000000;">&#40;</span>VerbsDiagnostic.<span style="color: #0000FF;">Test</span>, <span style="color: #666666;">&quot;Pipeline&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span><br />
&nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> TestPipelineCommand <span style="color: #008000;">:</span> Cmdlet<br />
&nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">#region Parameters</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// This is just a name parameter for decorating test cases :)</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#91;</span>Parameter<span style="color: #000000;">&#40;</span>Position <span style="color: #008000;">=</span> <span style="color: #FF0000;">0</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Mandatory <span style="color: #008000;">=</span> <span style="color: #0600FF;">false</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ValueFromPipelineByPropertyName <span style="color: #008000;">=</span> <span style="color: #0600FF;">false</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HelpMessage <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;A Name for Verbose output&quot;</span><span style="color: #000000;">&#41;</span>, ValidateNotNullOrEmpty<span style="color: #000000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> Name<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> _name<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span> _name <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> <span style="color: #FF0000;">string</span> _name <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;TestPipeline&quot;</span><span style="color: #008000;">;</span><br />
<br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#91;</span>Parameter<span style="color: #000000;">&#40;</span>Position <span style="color: #008000;">=</span> <span style="color: #FF0000;">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Mandatory <span style="color: #008000;">=</span> <span style="color: #0600FF;">true</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ValueFromPipeline <span style="color: #008000;">=</span> <span style="color: #0600FF;">true</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HelpMessage <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Help Text&quot;</span><span style="color: #000000;">&#41;</span>, ValidateNotNullOrEmpty<span style="color: #000000;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">object</span> InputObject<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get <span style="color: #000000;">&#123;</span> <span style="color: #0600FF;">return</span> _input<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set <span style="color: #000000;">&#123;</span> _input <span style="color: #008000;">=</span> value<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> <span style="color: #FF0000;">object</span> _input<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">private</span> <span style="color: #FF0000;">bool</span> _isArgument <span style="color: #008000;">=</span> false<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080;">#endregion</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> BeginProcessing<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteVerbose<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Begin Processing {0}&quot;</span>, Name<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>_input <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span> <span style="color: #008000;">&amp;&amp;</span> _input <a href="http://www.google.com/search?q=is+msdn.microsoft.com"><span style="color: #008000;">is</span></a> ICollection<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _isArgument <span style="color: #008000;">=</span> true<span style="color: #008000;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StringBuilder output <span style="color: #008000;">=</span> <a href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="color: #008000;">new</span></a> StringBuilder<span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;There's input: &quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> _in <span style="color: #0600FF;">in</span> <span style="color: #000000;">&#40;</span>ICollection<span style="color: #000000;">&#41;</span>_input<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output.<span style="color: #0000FF;">AppendFormat</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;{0}, &quot;</span>, _in<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteVerbose<span style="color: #000000;">&#40;</span>output.<span style="color: #0000FF;">ToString</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">BeginProcessing</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> ProcessRecord<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #008000;">!</span>_isArgument<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// This is the normal ProcessRecord code</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteVerbose<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Process: {0}&quot;</span>, _input<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteObject<span style="color: #000000;">&#40;</span>_input<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008080; font-style: italic;">// This is what we have to do unwrap -InputObject as Arg</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ICollection _collection <span style="color: #008000;">=</span> _input<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _isArgument <span style="color: #008000;">=</span> false<span style="color: #008000;">;</span> <span style="color: #008080; font-style: italic;">// unset isCollection before recursing</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> _in <span style="color: #0600FF;">in</span> <span style="color: #000000;">&#40;</span>ICollection<span style="color: #000000;">&#41;</span>_collection<span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; InputObject <span style="color: #008000;">=</span> _in<span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ProcessRecord<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> EndProcessing<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WriteVerbose<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">String</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;End Processing {0}&quot;</span>, Name<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0600FF;">base</span>.<span style="color: #0000FF;">EndProcessing</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #000000;">&#125;</span><br />
<span style="color: #000000;">&#125;</span></div>]]></content:encoded>
			<wfw:commentRss>http://huddledmasses.org/writing-cmdlets-for-the-powershell-pipeline/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

