{"id":1174,"date":"2011-07-14T00:00:00","date_gmt":"2011-07-14T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/down-the-rabbit-hole-a-study-in-powershell-pipelines-functions-and-parameters\/"},"modified":"2021-05-11T15:56:26","modified_gmt":"2021-05-11T15:56:26","slug":"down-the-rabbit-hole-a-study-in-powershell-pipelines-functions-and-parameters","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/down-the-rabbit-hole-a-study-in-powershell-pipelines-functions-and-parameters\/","title":{"rendered":"Down the Rabbit Hole- A Study in PowerShell Pipelines, Functions, and Parameters"},"content":{"rendered":"<div id=\"pretty\">\n<h2>Contents <\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1326-img51.gif\" class=\"float-right\" alt=\"1326-img51.gif\" \/><\/p>\n<ul>\n<li><a href=\"#first\">Syntax of a Function Call<\/a>  <\/li>\n<li><a href=\"#second\">Typed Parameters <\/a> <\/li>\n<li><a href=\"#third\">Input Sources and Precedence<\/a>  <\/li>\n<li><a href=\"#fourth\">Input Combinations<\/a>\n<ul>\n<li><a href=\"#fifth\">Direct Input\/Positional Parameters<\/a>  <\/li>\n<li><a href=\"#sixth\">Direct Input\/Named Parameters<\/a>  <\/li>\n<li><a href=\"#seventh\">Default Values<\/a>  <\/li>\n<li><a href=\"#eighth\">Pipeline Input\/Explicit Parameters<\/a>  <\/li>\n<li><a href=\"#ninth\">Pipeline Input\/Implicit<\/a> <\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#tenth\">Expanding the Notion of a Function for Pipeline Input<\/a>  <\/li>\n<li><a href=\"#eleventh\">Function Template Wallchart <\/a>\n<ul>\n<li><a href=\"#twelveth\">Equivalence Classes of Input<\/a>  <\/li>\n<li><a href=\"#thirteenth\">The Test Vehicle<\/a>  <\/li>\n<li><a href=\"#fourteenth\">Template Organization<\/a>  <\/li>\n<li><a href=\"#fifteenth\">Which Template Delivers the Best Results?<\/a> <\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#sixteenth\">Conclusion<\/a>  <\/li>\n<li><a href=\"#seventeenth\">Footnotes<\/a>  <\/li>\n<li><a href=\"#eighteenth\">Epilogue <\/a><\/li>\n<\/ul>\n<p class=\"start\">PowerShell&#226;&#162; is a shell language for Windows&#194;&#174; that combines the best of a scripting language with the best of a compiled language. PowerShell lets you do anything batch files could do but with much more power, elegance, and simplicity, and it lets you do anything C# can do too; indeed, you can easily invoke any .NET code you like from within PowerShell. So naturally, PowerShell provides the capability to create functions, so that you can encapsulate code as you would with a &#8220;regular&#8221; programming language. To create and use PowerShell functions effectively, however, you must properly understand the rules of engagement.<\/p>\n<p class=\"pullout\"><i>&#8220;Why, sometimes I&#8217;ve believed as many as six impossible things before breakfast.&#8221;<br \/><\/i>&#8211;The White Queen. Chapter 5, Through the Looking Glass (Lewis Carroll)<i><\/i><\/p>\n<p>Functions, beyond their most basic form, are fraught with pitfalls and seemingly perplexing results. Indeed, you may on occasion find yourself thinking &#8221; that is just not possible!?!&#8221; <\/p>\n<p>As you read this article, you may discover that there are fewer &#8220;impossibilities&#8221; than you first thought&#8230;<\/p>\n<p class=\"pullout\">&#8220;Oh dear, what nonsense I&#8217;m talking!&#8221;<br \/>&#8211;Alice. Chapter 2, Through the Looking Glass (Lewis Carrol)<i><\/i><\/p>\n<p><i>What&#8217;s the connection to Alice in Wonderland? Learning a new technology is a journey quite analogous to that which Alice experienced: unexpected twists, tangents leading off to nowhere, delightful surprises&#8230; This is the second installment of my PowerShell adventure; see my first tale on this journey at <a href=\"http:\/\/www.simple-talk.com\/dotnet\/.net-tools\/harnessing-powershells-string-comparison-and-list-filtering-features\/\">Harnessing PowerShell&#8217;s String Comparison and List-Filtering Features<\/a>.<\/i><\/p>\n<h2 id=\"first\">Syntax of a Function Call<\/h2>\n<p>In <a href=\"http:\/\/tfl09.blogspot.com\/2010\/09\/calling-functions-in-powershell.html\"><i>Calling Functions in PowerShell<\/i><\/a>, Thomas Lee provides a succinct example of one pitfall that even experienced PowerShell scripters will occasionally tumble into-writing a basic function call that produces unexpected results. Here is my version of his script, revised for clarity and exposition:<\/p>\n<div class=\"atable\">\n<table>\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function f($a, $b, $c)<\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160; &#8220;`$a=$a&#8221;<\/p>\n<p>&#160;&#160;&#160; &#8220;`$b=$b&#8221;<\/p>\n<p>&#160;&#160;&#160; &#8220;`$c=$c&#8221;<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>write-host<\/b> <i>-BackgroundColor<\/i> Red &#8216;(1) f(&#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;)&#8217;<\/p>\n<p>f(&#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;)<\/p>\n<p><b>write-host<\/b> <i>-BackgroundColor<\/i> Red &#8216;(2) f &#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;&#8216;<\/p>\n<p>f &#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;<\/p>\n<p>#write-host -BackgroundColor Red &#8216;(3) f (&#8220;Foo&#8221; &#8220;Bar&#8221; &#8220;foobar&#8221;)&#8217;<\/p>\n<p>#f (&#8220;Foo&#8221; &#8220;Bar&#8221; &#8220;foobar&#8221;)<\/p>\n<p><b>write-host<\/b> <i>-BackgroundColor<\/i> Green &#8216;(4) f &#8220;Foo&#8221; &#8220;Bar&#8221; &#8220;foobar&#8221;&#8216;<\/p>\n<p>f &#8220;Foo&#8221; &#8220;Bar&#8221; &#8220;foobar&#8221;<\/p>\n<p><b>write-host<\/b> <i>-BackgroundColor<\/i> Green &#8216;(5) f -c &#8220;foobar&#8221; -a &#8220;Foo&#8221; -b &#8220;Bar&#8221;&#8216;<\/p>\n<p>f <i>-c<\/i> &#8220;foobar&#8221; <i>-a<\/i> &#8220;Foo&#8221; <i>-b<\/i> &#8220;Bar&#8221;<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>(1) f(&#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;)<\/p>\n<p>$a=Foo Bar foobar<\/p>\n<p>$b=<\/p>\n<p>$c=<\/p>\n<p>(2) f &#8220;Foo&#8221;,&#8221;Bar&#8221;,&#8221;foobar&#8221;<\/p>\n<p>$a=Foo Bar foobar<\/p>\n<p>$b=<\/p>\n<p>$c=<\/p>\n<p>(4) f &#8220;Foo&#8221; &#8220;Bar&#8221; &#8220;foobar&#8221;<\/p>\n<p>$a=Foo<\/p>\n<p>$b=Bar<\/p>\n<p>$c=foobar<\/p>\n<p>(5) f -c &#8220;foobar&#8221; -a &#8220;Foo&#8221; -b &#8220;Bar&#8221;<\/p>\n<p>$a=Foo<\/p>\n<p>$b=Bar<\/p>\n<p>$c=foobar<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\"><strong>Example 1<\/strong>: Writing a basic function call<\/p>\n<p class=\"pullout\"><i>I think I should understand that better, if I had it written down: but I can&#8217;t quite follow it as you say it.<br \/><\/i>&#8211;Alice, Chapter 9, Alice&#8217;s Adventures in Wonderland (Lewis Carroll)<i><\/i><\/p>\n<p>This script defines a function <b>f<\/b> that takes three parameters and simply writes out their values. The main code (the <b>Call<\/b> section of the table) writes out a function call variation and then executes that variation, producing the tidy, though curious, result shown. <\/p>\n<p>Well, then, let me explain it a bit further:<\/p>\n<div class=\"indent\">\n<p>Variation (1) looks like a typical function call (e.g. C#) but all the parameters end up in <span class=\"Code\">$a<\/span>, with nothing in <span class=\"Code\">$b<\/span> or <span class=\"Code\">$c<\/span>! (I&#8217;ve highlighted it in red, because this is not the desired outcome.) This result occurs because parentheses in PowerShell do <i>not<\/i> signify function arguments; rather they signify an expression to execute. In this case, the expression returns an array of 3 elements. That result is then supplied as the first positional parameter of the function, leaving nothing left for the remaining parameters. You can combat this pitfall easily with the <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/dd347614.aspx\">Set-StrictMode<\/a> cmdlet: <\/p>\n<pre class=\"lang:c# theme:vs2012\">Set-StrictMode -Version Latest<\/pre>\n<p>Alas, just like in Visual Basic&#194;&#174;, PowerShell does not enable strict mode by default-it is up to you to enable it in your scripts and modules in order to catch the improper use of parentheses when calling a function, (among other things). Do not be lulled into thinking of strict mode as a fail-safe for all pitfalls, however! Even just adding a space between the function name and the left parenthesis makes strict mode turn a blind eye to a potential problem-see the syntax pitfalls section of the accompanying wallchart. <\/p>\n<p>Variation (2) produces&#8230; the same thing! This is because commas also indicate members of an array, even when not contained in parentheses. The results are thus the same as for Variation (1) but through quite a different mechanism.<\/p>\n<p>Variation (3) is commented out in the code because it is not syntactically valid. Remember that parentheses indicate an expression to evaluate, but a space-separated list is not a valid expression. Space-separated items are valid only when used as individual parameters in a function call.<\/p>\n<p>&#160;Variation (4) (highlighted in green) reveals the true way to call a function with positional parameters-separate the parameters with white space, and no parentheses! <\/p>\n<p>Finally, variation (5) shows that you are not limited to <i>positional<\/i> parameters; you may also use <i>named<\/i> parameters, in which case the order is not significant.<\/p>\n<\/div>\n<h2 id=\"second\">Typed Parameters<\/h2>\n<p>Just as PowerShell does not set strict mode by default, it does not require you to strongly type your functional parameters (sigh). So you can define a function to square an integer like this:<\/p>\n<pre class=\"lang:c# theme:vs2012\">Function f($x)\r\n{\r\n&#160;&#160;&#160;&#160;&#160; \"`$x squared is \" + ($x * $x)\r\n}\r\n<\/pre>\n<p>Executing <b>f 15<\/b> yields 225. But passing a string (e.g. <b>f &#8220;a&#8221;<\/b>) results in an error on the line attempting to use <span class=\"Code\">$x<\/span> as an integer. While in this case the error is readily revealed, <i>your<\/i> code may or may not make it so obvious. PowerShell does not <i>require<\/i> you to type your parameters but it does allow you to. Thus, it is much better to let the function&#8217;s signature serve as the arbiter of good inputs by specifying the type of the parameters (using any .NET type name):<\/p>\n<pre class=\"lang:c# theme:vs2012\">Function f([int]$x)\r\n{\r\n&#160;&#160;&#160;&#160;&#160; \"`$x squared is \" + ($x * $x)\r\n}\r\n<\/pre>\n<h2 id=\"third\">Input Sources and Precedence<\/h2>\n<p><i>Cmdlets<\/i> are similar to <i>functions<\/i>; the primary difference is that a cmdlet is written in a compiled .NET language while a function is written in PowerShell. With the advent of PowerShell 2.0, however, you can create functions that can perform as much &#8220;heavy lifting&#8221; as cmdlets written in C#. Notably, you can create a function that can accept either direct inputs or pipeline inputs, which is the point of interest here.<\/p>\n<p>There are <i>three<\/i> possible input sources for a function: no input, direct input, and pipeline input. These sources may be combined within a single function, e.g. one parameter can accept pipeline input while another takes direct input. But you can also combine them for a single parameter, allowing a single parameter to accept direct or pipeline input. <\/p>\n<p>Since PowerShell has only three input sources, the question of precedence is quite straightforward. (Compare this to, for example, Windows Presentation Foundation (WPF) dependency properties, where the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms743230.aspx\">precedence list<\/a> contains 11 possible sources!) Without further ado, the precedence list for PowerShell is just this:<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p class=\"atable\">Direct input <i>-or-<\/i> Pipeline input<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p class=\"atable\">Default value<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&#160;That is, you may supply direct input or pipeline input, but not both. If neither is supplied, the default value, if any, applies.<\/p>\n<p>For illustrative purposes, consider the oft-used <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/dd347686.aspx\">Get-ChildItem<\/a><span class=\"MsoHyperlink\"> <\/span>cmdlet. Here is its syntax summary:<\/p>\n<pre>Get-ChildItem \r\n[[-Path] &lt;string[]&gt;] [[-Filter] &lt;string&gt;]\r\n[-Exclude &lt;string[]&gt;] [-Force] [-Include &lt;string[]&gt;]\r\n[-Name] [-Recurse] [-UseTransaction] [&lt;CommonParameters&gt;]\r\n<\/pre>\n<p>Focusing on the <b>Path<\/b> parameter, the documentation for that parameter says that the default value is &#8220;.&#8221; indicating the current directory, and that the parameter accepts pipeline input. (All parameters accept direct input so it is not explicitly mentioned in the documentation.) Thus, a call with no input&#8230;<\/p>\n<pre>Get-ChildItem<\/pre>\n<p>&#8230;applies the default argument, returning a listing of the contents of the current directory. If you provide an explicit parameter, you may do so either as direct input or as pipeline input. Hence, these two statements are exactly equivalent and return the contents of the &#8220;tmp&#8221; directory:<\/p>\n<pre class=\"lang:c# theme:vs2012\">Get-ChildItem \"tmp\"&#160;&#160;&#160; # direct input\r\n\"tmp\" | Get-ChildItem&#160; # pipeline input<\/pre>\n<p>If you attempt to supply <i>both<\/i> direct input and pipeline input&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">\"tmp\" | Get-ChildItem \"tmp\"<\/pre>\n<p>&#8230; PowerShell generates an error that indicates the problem in a rather circuitous fashion:<\/p>\n<pre class=\"lang:c# theme:vs2012\">Get-ChildItem : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.<\/pre>\n<p>What that message is really saying is that, after applying one input to the <b>Path<\/b> parameter, the command also attempted to provide a second input to the same parameter. But since any parameter can have input only from one source at a time, the error says it does not have a match for the second input source to any parameter. <\/p>\n<h2 id=\"fourth\">Input Combinations<\/h2>\n<p>There are a number of possible combinations of input source and parameter types to consider.<\/p>\n<h3 id=\"fifth\">Direct Input\/Positional Parameters<\/h3>\n<p>Parameters in the call are matched to parameters in the function signature by their order or position: the first parameter in the signature takes the first parameter from the call, the second takes the second, and so on. If the signature specifies more parameters than you supply in the call, the leftover parameters assume either default values (if you have provided them) or null.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f $x $y $z<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Signature<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f ( $a, $b, $c)<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Implicit Assignment<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$a = $x, $b = $y, $c = $z<\/b><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3 id=\"sixth\">Direct Input\/Named Parameters<\/h3>\n<p>Parameters in the call are matched to parameters in the function signature by their names; the order in the call is irrelevant. If the signature specifies more parameters than you supply in the call, the leftover parameters assume either default values (if you have provided them) or null.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f -C $z -B $y -A $x<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Signature<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f ( $a, $b, $c)<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Implicit Assignment<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$a = $x, $b = $y, $c = $z<\/b><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3 id=\"seventh\">Default Values<\/h3>\n<p>Here, parameter <span class=\"Code\">$b<\/span> has a default value assigned in the function&#8217;s signature, while parameter <span class=\"Code\">$c<\/span> does not. A call providing only a value for parameter <span class=\"Code\">$a<\/span> results in <span class=\"Code\">$b<\/span> having the default value 25 and <span class=\"Code\">$c<\/span> having the value <span class=\"Code\">$null<\/span>.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f $x<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Signature<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f ( $a, $b = 25, $c)<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Implicit Assignment<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$a = $x, $b = 25, $c = $null<\/b><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h3 id=\"eighth\">Pipeline Input\/Explicit Parameters<\/h3>\n<p>Values in the pipeline are fed to a parameter that is set up to accept it. To wire it up, all you need to do is to attach the <b>ValueFromPipeline<\/b> attribute to a parameter in the signature. Assuming you have structured the body of the function appropriately (see next section), you will receive multiple outputs (one for each pipeline input), allowing you to continue pipelining if desired. The table below illustrates mixing a pipeline input (<span class=\"Code\">$a<\/span>) with direct inputs (<span class=\"Code\">$b<\/span>, <span class=\"Code\">$c<\/span>, and <span class=\"Code\">$d<\/span>), where <span class=\"Code\">$b<\/span> has an explicit value via a named parameter that overrides its default, <span class=\"Code\">$c<\/span> has neither default nor value, and <span class=\"Code\">$d<\/span> has no explicit value but has a default.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$x1,$x2,$x3 | f -B 111<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Signature<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f [Parameter(ValueFromPipeline=$True)]$a, $b=-1, $c, $d=999)<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Implicit<\/p>\n<p>Assignment<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$a = $x1, $b = 111, $c = $null, $d=999<\/b><\/p>\n<p><b>$a = $x2, $b = 111, $c = $null, $d=999<\/b><\/p>\n<p><b>$a = $x3, $b = 111, $c = $null, $d=999<\/b><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>You may, in fact, specify more than one parameter to receive pipeline input. In such a case, each parameter sees the <i>same<\/i> value from the pipeline at the same time. Example 2 does so for <span class=\"Code\">$p1<\/span> and <span class=\"Code\">$p3<\/span> but not for <span class=\"Code\">$p2<\/span>:<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function Get-PipelineToMultipleParameters(<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; [Parameter(ValueFromPipeline=$True)]$p1 = &#8220;default&#8221;,<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; $p2 = &#8220;non-pipe&#8221;,<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; [Parameter(ValueFromPipeline=$True)]$p3 = &#8220;xyz&#8221;<\/p>\n<p>)<\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; Process { return &#8220;`$p1=$p1 :: `$p2=$p2 :: `$p3=$p3&#8221; }<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>25,49 | Get-PipelineToMultipleParameters<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>$p1=25 :: $p2=non-pipe :: $p3=25<\/p>\n<p>$p1=49 :: $p2=non-pipe :: $p3=49<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">&#160;Example 2: Specifying multiple parameters to receive the pipeline input<\/p>\n<p>The call sends two values as pipeline input to the <span class=\"Code\">Get-PipelineToMultipleParameters<\/span> function resulting in one line of output for each input. <span class=\"Code\">$p1<\/span> and <span class=\"Code\">$p3<\/span> will always contain the same pipeline input. Since <span class=\"Code\">$p2<\/span> does not take input from the pipeline, nor does it have a direct input supplied, it assumes its default value.<\/p>\n<h3 id=\"ninth\">Pipeline Input\/Implicit<\/h3>\n<p>Even if your function defines no parameters at all, it can still process pipeline input. The standard PowerShell technique for iterating through an array (see <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/dd347733.aspx\">about_Foreach<\/a>) is to pipe the array into a <b>foreach<\/b> loop and access each object in the array with the special <b>$_<\/b> variable (foreach has a convenient alias &#8220;%&#8221;&#160; because it is used so often in this type of context):<\/p>\n<pre class=\"lang:c# theme:vs2012\">\"abc\", 25.4, 1, -1, \"nonesuch\" | % { \"value is $_\" }<\/pre>\n<p>You can feed pipeline input into your function in just the same way.&#160; <\/p>\n<div class=\"atable\">\n<table class=\"MsoTableMediumGrid1Accent3\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$x1,$x2,$x3 | f<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Signature<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>f<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Implicit Assignment<\/p>\n<\/td>\n<td valign=\"top\">\n<p><b>$_ = $x1<\/b><\/p>\n<p><b>$_ = $x2<\/b><\/p>\n<p><b>$_ = $x3<\/b><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>The next section expounds upon this deceptively simple looking practice in depth.<\/p>\n<h2 id=\"tenth\">Expanding the Notion of a Function for Pipeline Input<\/h2>\n<p>The discourse thus far has operated under the assumption that a function has this basic structure:<\/p>\n<p><span class=\"Code\">function &lt;<i>name<\/i>&gt; ( { &lt;<i>parameter<\/i>&gt; } )<\/span><\/p>\n<p><span class=\"Code\">{<\/span><\/p>\n<p><span class=\"Code\">&#160;&#160;&#160;&#160;&#160; &lt;<i>statement list<\/i>&gt;<\/span><\/p>\n<p><span class=\"Code\">}<\/span><\/p>\n<p>That structure works fine if you are only interested in direct input. To allow for pipeline input, you need to expand a bit more of the true structure of a PowerShell function:<\/p>\n<p><span class=\"Code\">function &lt;<i>name<\/i>&gt; ( { &lt;<i>parameter<\/i>&gt; } )<\/span><\/p>\n<p><span class=\"Code\">{<\/span><\/p>\n<p><span class=\"Code\">&#160;&#160;&#160;&#160;&#160; begin&#160;&#160; { &lt;<i>statement list<\/i>&gt; }<\/span><\/p>\n<p><span class=\"Code\">&#160;&#160;&#160;&#160;&#160; process { &lt;<i>statement list<\/i>&gt; }<\/span><\/p>\n<p><span class=\"Code\">&#160;&#160;&#160;&#160;&#160; end&#160;&#160;&#160;&#160; { &lt;<i>statement list<\/i>&gt; }<\/span><\/p>\n<p><span class=\"Code\">}<\/span><\/p>\n<p>The <b>begin<\/b> block runs once, at the start of pipeline input before any of the input is read. The <b>process<\/b> block runs once for each object in the pipeline. At the conclusion of pipeline input, the <b>end<\/b> block runs. The PowerShell documentation (<a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/dd347712.aspx\">about_Functions<\/a>) provides two examples that are worth examining here. The first shows that the <b>begin<\/b> block indeed executes before the pipeline is opened and that the <b>end<\/b> block executes only once all pipeline data has been received. Note that the special <b>$input<\/b> variable contains the pipeline data.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function Get-PipelineBeginEnd <\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160; begin {&#8220;Begin: The input is $input&#8221;}<\/p>\n<p>&#160;&#160;&#160; end {&#8220;End:&#160;&#160; The input is $input&#8221; }<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>1,2,4 | Get-PipelineBeginEnd<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Begin: The input is <\/p>\n<p>End:&#160;&#160; The input is 1 2 4<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">Example 3: Showing <b>begin<\/b> and <b>end<\/b> blocks in a PowerShell function<\/p>\n<p>The next example shows how you could actually consume the pipeline data sequentially using the <b>process<\/b> block. And I mean consume <b><i>non<\/i><\/b>-metaphorically-observe that when the <b>end<\/b> block is executed the <b>$input<\/b> variable is now empty!<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function Get-PipelineInput<\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160; process {&#8220;Processing:&#160; $_ &#8221; }<\/p>\n<p>&#160;&#160;&#160; end {&#8220;End:&#160;&#160; The input is: $input&#8221; }<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>1,2,4 | Get-PipelineInput<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Processing:&#160; 1 <\/p>\n<p>Processing:&#160; 2 <\/p>\n<p>Processing:&#160; 4 <\/p>\n<p>End:&#160;&#160; The input is:<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">Example 4: Consuming the pipeline data sequentially using the <b>process<\/b> block<\/p>\n<p>The other important point to note from this example is that <b>$input<\/b> represents <i>all<\/i> the pipeline data (what it contains will vary depending on what you have consumed so far) while the <b>$_<\/b> special variable, on the other hand, contains the <i>current<\/i> pipeline object.<\/p>\n<p>Let me add a couple of further examples to reveal even more about pipeline manipulation. Example 4, above, showed how you could process an individual pipeline object with the <b>$_<\/b> variable. But you can also process each pipeline object with the <b>$input<\/b> variable itself. This next example is effectively the same as Example 4, but now it uses <b>$input<\/b> in the <b>end<\/b> block instead of <b>$_<\/b> in the <b>process<\/b> block. Watch out though; the <b>$_<\/b> variable is doing something very different now! Previously, it received elements from the pipeline feeding the function, which did not appear explicitly in the code. Here, it is receiving elements from the explicitly shown, local pipeline.<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function Get-PipelineInputFromInput<\/p>\n<p>{<\/p>\n<p>&#160; end {<\/p>\n<p>&#160;&#160;&#160; $input | <b>%<\/b> {&#8220;Processing:&#160; $_ &#8221; }<\/p>\n<p>&#160;&#160;&#160; &#8220;`input after processing: $input&#8221;<\/p>\n<p>&#160; }<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>1,2,4 | Get-PipelineInputFromInput<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Processing:&#160; 1 <\/p>\n<p>Processing:&#160; 2 <\/p>\n<p>Processing:&#160; 4 <\/p>\n<p>input after processing: <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">Example 5: Processing each pipeline object with the <b>$input<\/b> variable<\/p>\n<p>One reason to use <b>$input<\/b> to process your functional pipeline in the <b>end<\/b> block rather than <b>$_<\/b> in the <b>process<\/b> block is that you have more control over the pipeline with the former. With <b>$_<\/b>, you have access to each pipeline object just once. But <b>$input<\/b> is actually a .NET <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.collections.ienumerator.aspx\">IEnumerator<\/a> object. As such, you can invoke its <b>Reset<\/b> method to restore the position to the start of its data. In Example 6, a couple of extra lines are added to the end of the function showing that you can do repeated processing of the pipeline if you like.<b><\/b><\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>function Get-PipelineInputFromInput<\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160; $input | <b>%<\/b> {&#8220;Processing:&#160; $_ &#8221; }<\/p>\n<p>&#160;&#160;&#160; &#8220;`input after processing: $input&#8221;<\/p>\n<p>&#160;&#160;&#160; $input.Reset()<\/p>\n<p>&#160;&#160;&#160; &#8220;`input after reset: $input&#8221;<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>1,2,4 | Get-PipelineInputFromInput<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Processing:&#160; 1 <\/p>\n<p>Processing:&#160; 2 <\/p>\n<p>Processing:&#160; 4 <\/p>\n<p>input after processing: <\/p>\n<p>input after reset: 1 2 4<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">Example 6: Repeated processing of the pipeline<\/p>\n<p>One other way to work with <b>$input<\/b> that I often find easier is to convert from an enumerator to an array. Add a line of code like this as your first (and only) access of the <b>$input<\/b> enumerator to copy your pipeline data into a regular array:<\/p>\n<pre class=\"lang:c# theme:vs2012\">$myData = @($input)<\/pre>\n<p>&#8230;and you can then manipulate it however you please (thanks to <a href=\"http:\/\/dmitrysotnikov.wordpress.com\/2008\/11\/26\/input-gotchas\/\">Dmitry Sotnikov<\/a> for this tip).<\/p>\n<p>I introduced one other subtle difference in Example 6; I removed the <b>end<\/b> block. That change is completely cosmetic-a function without explicit <b>begin<\/b>, <b>process<\/b>, and <b>end<\/b> blocks operates as if all the code is in the <b>end<\/b> block implicitly. Similarly, you can have all your code run implicitly in the <b>process<\/b> block by simply creating a <i>filter<\/i> instead of a <i>function<\/i>:<\/p>\n<div class=\"atable\">\n<table class=\"MsoTableGrid\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Function<\/p>\n<\/td>\n<td valign=\"top\">\n<p>filter Get-PipelineInput<\/p>\n<p>{<\/p>\n<p>&#160;&#160;&#160; &#8220;Processing:&#160; $_ &#8220;<\/p>\n<p>}<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Call<\/p>\n<\/td>\n<td valign=\"top\">\n<p>1,2,4 | Get-PipelineInput<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Result<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Processing:&#160; 1 <\/p>\n<p>Processing:&#160; 2 <\/p>\n<p>Processing:&#160; 4 <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p class=\"caption\">Example 7: Creating a filter to run all the code in the <b>process<\/b> block<\/p>\n<h2 id=\"eleventh\">Function Template Wallchart<\/h2>\n<p>All of the above has laid the groundwork for the true goal of this article: to illustrate how to structure a function to accept multiple input sources. It is also just as important to understand how <b><i>not<\/i><\/b> to. The wallchart accompanying this article distills a key set of templates and evaluates each template against possible inputs. Here is just a thumbnail of the wallchart, which is downloadable from the bottom of the article.<\/p>\n<p><a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1326-PS_functions_wallchart_1_0_1.htm\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1326-PS_functions_wallchart_1_0_1_Thumbnail.PNG\" alt=\"1326-PS_functions_wallchart_1_0_1_Thumbn\" \/><\/a>  <\/p>\n<h3 id=\"twelveth\">Equivalence Classes of Input<\/h3>\n<p>The central fixture of the wallchart is a matrix of most typical function structures with a report of how each one performs against all possible inputs, characterized by the six equivalence classes listed across the top of the wallchart:<\/p>\n<ol>\n<li>No Input  <\/li>\n<li>Null  <\/li>\n<li>Empty String  <\/li>\n<li>Scalar  <\/li>\n<li>List  <\/li>\n<li>List with Null\/Empty <\/li>\n<\/ol>\n<p>Because this set of inputs may come either from direct input or from pipeline input, there are actually 12 tests to be performed on each function. The results of executing each function template with each of the 12 tests comprise the main body of the matrix.<\/p>\n<h3 id=\"thirteenth\">The Test Vehicle<\/h3>\n<p>The test program, shown in its entirety here, is quite short. The bulk of it is a list of the twelve inputs and the desired result for each input, each introduced with the <b>Assert-Expression<\/b> command.<\/p>\n<pre class=\"lang:c# theme:vs2012\">cls\r\nSet-StrictMode -Version Latest\r\nImport-Module TestParameters\\TestParamFunctions -Force\r\nImport-Module CleanCode\\Assert-Expression -Force\r\n&#160;\r\n$funcList = (Get-Module TestParamFunctions).ExportedCommands.Keys\r\n$funcList | sort | % {\r\n&#160;&#160;&#160;&#160;&#160;&#160; Write-Host -BackgroundColor DarkGreen \"`n=== $_ ===\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0}' -f $_) \"default\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0} $null' -f $_) $null\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0} \"\"' -f $_) \"\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0} \"one\"' -f $_) \"one\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0} \"one\",\"two\"' -f $_) \"one\",\"two\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('{0} \"one\",$null,\"two\",\"\"' -f $_) \"one\",$null,\"two\",\"\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('@() | {0}' -f $_) \"default\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('$null | {0}' -f $_) $null\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('\"\" | {0}' -f $_) \"\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('\"one\" | {0}' -f $_) \"one\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('\"one\",\"two\" | {0}' -f $_) \"one\",\"two\"\r\n&#160;&#160;&#160;&#160;&#160;&#160; Assert-Expression ('\"one\",$null,\"two\",\"\" | {0}' -f $_) \"one\",$null,\"two\",\"\"\r\n}\r\nWrite-Host -BackgroundColor DarkGreen \"`n=== Done ===\"\r\n<\/pre>\n<p>This test program relies on two library modules. <b>TestParamFunctions<\/b> is a custom library module that enumerates each function template shown on the wallchart. <b>Assert-Expression<\/b>, from my open-source CleanCode library<a href=\"#footnote1\">1<\/a>, provides the Assert-Expression function that lets you validate the execution of an expression against a desired result. For the above program to run, you must install the library modules so that PowerShell can find them (either in a user folder at &#160;<code>...<br \/>&#160; user\\documents\\windowspowershell\\modules<\/code><br \/>&#160;or a system folder at &#160;<code>...<br \/>&#160; windows\\system32\\windowspowershell\\V1.0\\modules<\/code>).<\/p>\n<p>There are other validation packages available, of course, but I prefer my version because it provides a unique color-coded result that lets you instantly identify the parts that fail. It provides in concise fashion: the inputs to the test, indication of passing tests in green, indication of failing tests in red, and it individually marks which elements of the expected results mismatch with actual results. Here is an excerpt for one function template with all 12 input combinations.<\/p>\n<p class=\"illustration\"><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1326-img46.jpg\" alt=\"1326-img46.jpg\" \/><\/p>\n<p class=\"caption\">Figure 1: Excerpt of test results from one function template<\/p>\n<p>Notice that the test program above specifies the set of inputs to send to each test, but actually has no knowledge about the list of tests itself! The magic is in this line of code: <\/p>\n<pre class=\"lang:c# theme:vs2012\">$funcList = (Get-Module TestParamFunctions).ExportedCommands.Keys<\/pre>\n<p>&#8230;which simply enumerates all the tests defined in the TestParamFunctions module. Thus, if you want to add your own variations, you need only edit the library module and the test program will automatically incorporate them in the test suite.<\/p>\n<h3 id=\"fourteenth\">Template Organization<\/h3>\n<p>The 10 templates shown in the wallchart are arranged into three groups. The goal is to make each template more sophisticated until a template can handle all the input possibilities. <\/p>\n<p>Group A introduces the most basic function structure for the three available techniques to access an input: the direct parameter, the <b>$_<\/b> variable for pipeline input, and the <b>$input<\/b> variable for pipeline input. This na&#195;&#175;ve approach delivers only about half of the correct answers: the direct parameter technique allows all the tests with direct input to pass, while the two pipeline techniques allow all the tests with pipeline input to pass. <\/p>\n<p>Group B adds a default value to each parameter in the hope of improving the &#8220;No input&#8221; case. This goal is met moving from template A_1 to template B_1 but, alas, does nothing to improve the results for B_2 or B_3.<\/p>\n<p>The templates in Group C bring sufficient sophistication to handle both direct and pipeline inputs. Group C is subdivided into two templates that use the pipeline input from <b>$_<\/b> (templates C_1 and C_2) and two templates that use <b>$input<\/b> (templates C_3 and C_4). <\/p>\n<p>The only difference between C_1 and C_2 is the <b>Parameter<\/b> attribute attached to the <b>$item<\/b> parameter in C_2. The template yields much better results when the attribute is present, as is appropriate for a pipeline-receptive input, yielding 11 out of 12 correct for C_2 compared to 8 out of 12 correct for C_1.<\/p>\n<p>Templates C_3 and C_4 also differ in the <b>Parameter<\/b> attribute, but C_3 needs one additional statement to check the existence of the <b>$item<\/b> parameter; without that statement-and with StrictMode enabled in the main test program-PowerShell emits an error on one of the 12 tests. (It seems rather peculiar that a parameter in the function&#8217;s signature could be undefined in its own body, but such is the case here!)<\/p>\n<h3 id=\"fifteenth\">Which Template Delivers the Best Results?<\/h3>\n<p>The wallchart indicates that only C_3 and C_4 are robust enough to provide the correct result for all 12 input combinations. But what does &#8220;correct&#8221; mean in this context? <\/p>\n<p class=\"pullout\"><i>When I use a word it means just what I choose it to mean &#8211; neither more nor less.<br \/><\/i>&#8211;Humpty Dumpty, Chapter 6, Through the Looking Glass<i><\/i><\/p>\n<p>Though computing is the ultimate &#8220;black-and-white&#8221; realm-dealing with 1&#8217;s and 0&#8217;s-shades of grey often pop up when you least expect them. Most of the test cases actually <i>are<\/i> black and white. The interesting case is when you supply <i>no<\/i> input. For direct input, this is when you invoke the function without an argument, in which case the parameter assumes the default value. But when you consider pipeline inputs, what constitutes no input? The answer I propose is: an empty list. So I contend an empty list piped in should yield a default value for the parameter. But you could also argue that, from a pipeline, you would <i>never<\/i> get a default value; instead the &#8220;worst&#8221; you could get would be <span class=\"Code\">$null<\/span>. That philosophical difference is the difference between template C-2 and C-4. Two other considerations come to mind when considering which is the &#8220;right&#8221; answer:<\/p>\n<p>(1) Elegance of symmetry, in which the results are exactly symmetric between direct input and pipeline input: in the results of template C-3 and C-4, both rows of results are identical column-for-column.<\/p>\n<p>(2) Elegance of code: template C-4 is simpler than template C-3 while achieving the same result, even though it technically violates the requirement of indicating (with the <b>Parameter<\/b> attribute) that a parameter accepts pipeline input. But template C-2 is clearly more elegant than template C-4 using, in some sense, more of the built-in functionality to achieve pipeline inputs.<\/p>\n<p>Point (1) favors template C-3 or C-4; point (2) favors template C-2. Pick whichever fits best with your own style.<\/p>\n<h2 id=\"sixteenth\">Conclusion<\/h2>\n<p>There is always more to the story, but the above provides you with the vast majority of the information you need to be productive with PowerShell functions. Applying one of my favorite rules of writing, it is time for me to draw to a close:<\/p>\n<p class=\"pullout\"><i>Begin at the beginning and go on till you come to the end: then stop.<br \/><\/i>&#8211;The King, Chapter 12, Alice&#8217;s Adventures in Wonderland <i><\/i><\/p>\n<p>If you have been reluctant to try your hand at PowerShell functions due to their seemingly idiosyncratic nature, this reference and the accompanying wallchart should give you the tools you need to go at it with confidence!<\/p>\n<h2 id=\"seventeenth\">Footnotes<\/h2>\n<p><span id=\"footnote1\">1<\/span> My open source <a href=\"http:\/\/cleancode.sourceforge.net\/wwwdoc\/software.html\">CleanCode<\/a> library contains building blocks for C#, Perl, Java, SQL, and JavaScript, and will soon have a new section devoted to PowerShell, which will include the Assert-Expression module discussed in this article. Look for it in the fourth quarter of 2011.<\/p>\n<h2 id=\"eighteenth\">Epilogue<\/h2>\n<p><img decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1326-img4D.gif\" class=\"float-left\" alt=\"1326-img4D.gif\" \/><\/p>\n<p>&#8216;Would you tell me, please, which way I ought to go from here?&#8217; <br \/>&#8216;That depends a good deal on where you want to get to,&#8217; said the Cat. <br \/>&#8216;I don&#8217;t much care where &#8211; &#8216; said Alice. <br \/>&#8216;Then it doesn&#8217;t matter which way you go,&#8217; said the Cat. <br \/>&#8216;- so long as I get <em>somewhere<\/em>,&#8217; Alice added as an explanation. <br \/>&#8216;Oh, you&#8217;re sure to do that,&#8217; said the Cat, &#8216;if you only walk long enough.&#8217; <br \/>&#8211;Alice, Chapter 9, Alice&#8217;s Adventures in Wonderland (Lewis Carroll) <\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>For an experienced programmer to learn a new language can be a journey quite like Alice&#8217;s in wonderland. Paradoxes,  unexpected twists, blind tangents, bafflements and  nice surprises. Michael comes to the rescue of anyone learning PowerShell  with an explanation of how to use PowerShell functions.&hellip;<\/p>\n","protected":false},"author":221868,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,4204,4178,4635],"coauthors":[6802],"class_list":["post-1174","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-tools","tag-bi","tag-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221868"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=1174"}],"version-history":[{"count":7,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1174\/revisions"}],"predecessor-version":[{"id":90919,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/1174\/revisions\/90919"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=1174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=1174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=1174"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=1174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}