Archive

Posts Tagged ‘Powershell Pipeline’

Using PowerShell $MyInvocation.Pipelineposition for script logic

June 6th, 2012 No comments

This is an attempt to describe how we can use PowerShell pipeline and its position and length properties  to adapt script logic.  I have learned this while following Scripting Guys Blog , but I have run into an issue while using this feature.  I did ask this question to the experts out there on twitter, but due to limited character length I couldn’t explain my scenario clear enough.  Hence I thought I would write a short post on this to share with the experts out there and may be get some feedback on any better way of doing this.  No disregard, there are many write-up out there from the experts on this topic, so if you want to learn more about this go ahead and Bing it or Google it.

 

Below is a scrip snippet, with a function which will just print an email address from a name provided.

$myinvocation is a System.Management.Automation.InvocationInfo object, this variable can tell you many useful information about the cmdlet, fuction, or scripts being run. Things suchs as the path of the current script being run, the command being run etc. you can give a search in google using keyword $myinvocation

You can see above the members available on $myinvocation, my idea was about using pipelinelength and pipelineposition, pipelinelength tells the length of the complete command being run. For example if there is only one command like Get-Process then the length of the pipeline is 1 and if you use Get-ChildItem | Measure-Object then the lenth now is 2 and the cmdlet Get-ChildItem is at position 1 and Measure-Object is at position 2.

By this you can identify your script or function is run in piple line or in other words as an input to another cmdlet in the pipeline.  If my function’s position is less than the pipeline length then i am being used as an input and what that means is do not emit formatted output there rather send raw objects.  At the same time i can send my output in a desired format if my function is used at the end of the pipeline. Such as $myinput | Myfunction (here myfunction takes input from the pipeline but it does not have to send the object out as there is no cmdlets awaiting an object, its just a result on to the host).

When I call Get-MailAddress the pipeline position and length is 1 so its understood that output is not piped to any other cmdlet hence we will put a colored output on the screen  using Write-Host,  all is good.

 

When I call Get-MailAddress |Select-Object  - the function is called in between a pipeline,  meaning the output is requested to be piped to another cmdlet, hence the function sends the output as an object to the pipeline using write-output.

 

 The other way of executing the cmdlet $Result = Get-MailAddress , this were it doesn’t wok as expected by the end user. Its expected that the output be saved to variable $Result. But the output is send to the host using Write-Host and using color and there is nothing in $Result variable

 

Only work around I could figure out is $Result = Get-MailAddress | Select-Object , now the function is in middle of pipeline and it emits bare objects.

 

That’s about it, if you have a different way to solve this problem, or if this logic can be handled using different mechanism please do give feedback.