{"id":1045,"date":"2014-07-07T00:01:00","date_gmt":"2014-07-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/07\/07\/piping-results-from-one-powershell-cmdlet-to-another\/"},"modified":"2014-07-07T00:01:00","modified_gmt":"2014-07-07T00:01:00","slug":"piping-results-from-one-powershell-cmdlet-to-another","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/piping-results-from-one-powershell-cmdlet-to-another\/","title":{"rendered":"Piping Results from One PowerShell Cmdlet to Another"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, talks about piping the results from one cmdlet to another.\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\">&nbsp;Hey, Scripting Guy! I have a problem. When I pipe information from one Windows PowerShell cmdlet to anther (for example, when I use <b>Get-Process<\/b> and pipe it to <b>Stop-Process<\/b> ), sometimes it works, and sometimes it does not. This is not great. What is the deal? Can you help?\n&mdash;LR\n<img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\">&nbsp;Hello LR,\nMicrosoft Scripting Guy, Ed Wilson, is here. The nice thing about a hurricane is when it is gone. In Charlotte, we got some pretty heavy rain as a result of Hurricane Arthur, but nothing serious. Now we are enjoying the cool weather that followed that event. It seems like autumn outside.\nLR, using the Windows PowerShell pipeline is not really like a hurricane, but sometimes it seems unpredictable. Therefore, things can appear to go around in circles. The key to knowing what is going on is understanding parameter sets.\nFor example, if I use <b>Start-Process<\/b>, I can easily start a new process. I can then use <b>Get-Process<\/b> to retrieve that process. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; Start-Process notepad<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; get-Process notepad\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp; &nbsp;&nbsp;&#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; 84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp; 1508&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8112&nbsp;&nbsp; 110&nbsp;&nbsp;&nbsp;&nbsp; 0.08&nbsp;&nbsp; 5412 notepad\nIt would seem to make sense that I can now pipe the results to the <b>Stop-Process<\/b> cmdlet and stop the process. But if I do this, I get the following error message:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; get-Process notepad | Stop-Process notepad<\/p>\n<p style=\"margin-left:30px\">Stop-Process : Cannot bind parameter &#8216;InputObject&#8217;. Cannot convert the &#8220;notepad&#8221; value<\/p>\n<p style=\"margin-left:30px\">of type &#8220;System.String&#8221; to type &#8220;System.Diagnostics.Process&#8221;.<\/p>\n<p style=\"margin-left:30px\">At line:1 char:36<\/p>\n<p style=\"margin-left:30px\">+ get-Process notepad | Stop-Process notepad<\/p>\n<p style=\"margin-left:30px\">+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~~~~~~~<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidArgument: (:) [Stop-Process], ParameterBindingException<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Comman<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; ds.StopProcessCommand\nThe key is to realize this is not a &ldquo;bogus error.&rdquo; Rather, there is significant information here. It tells me that the cmdlet tries to bind the parameter <b>InputObject<\/b>, but that it does not work because &ldquo;notepad&rdquo; is a string and not a process object.<\/p>\n<h2>Three parameter sets<\/h2>\n<p>The <b>Stop-Process<\/b> cmdlet accepts the following three parameter sets:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; Get-Command Stop-Process -Syntax<\/p>\n<p style=\"margin-left:30px\">Stop-Process [-Id] &lt;int[]&gt; [-PassThru] [-Force] [-WhatIf] [-Confirm] [&lt;CommonParameters&gt;]\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">Stop-Process -Name &lt;string[]&gt; [-PassThru] [-Force] [-WhatIf] [-Confirm]<\/p>\n<p style=\"margin-left:30px\">[&lt;CommonParameters&gt;]\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">Stop-Process [-InputObject] &lt;Process[]&gt; [-PassThru] [-Force] [-WhatIf] [-Confirm]<\/p>\n<p style=\"margin-left:30px\">[&lt;CommonParameters&gt;]\nThe default parameter set is <b>ID<\/b>, which accepts an integer in the first position. To find this information about parameter sets, use the <b>Get-Command<\/b> cmdlet and pipe the output to <b>Select-Object<\/b> while expanding the <b>ParameterSets<\/b> parameter.\nHere is a sample of the output for the first parameter (<b>ID<\/b>). The output shows that <b>ID<\/b> is the default parameter set, and that <b>ID<\/b> appears in the first position and is mandatory. It also tells us that this parameter does not accept a value from the pipeline.<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; Get-Command Stop-Process | select -expand parametersets\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">Parameter Set Name: Id<\/p>\n<p style=\"margin-left:30px\">Is default parameter set: True\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; Parameter Name: Id<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ParameterType = System.Int32[]<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Position = 0<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsMandatory = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsDynamic = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; HelpMessage =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipeline = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipelineByPropertyName = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromRemainingArguments = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Aliases = {}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Attributes =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ParameterAttribute\nWhat about the <b>Name<\/b> parameter? Well, there is a <b>Name<\/b> parameter set. It is not the default parameter set, and it also does not accept a value from the pipeline. This is shown here:<\/p>\n<p style=\"margin-left:30px\">Parameter Set Name: Name<\/p>\n<p style=\"margin-left:30px\">Is default parameter set: False\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; Parameter Name: Name<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ParameterType = System.String[]<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Position = -2147483648<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsMandatory = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsDynamic = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; HelpMessage =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipeline = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipelineByPropertyName = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromRemainingArguments = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Aliases = {ProcessName}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Attributes =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.AliasAttribute<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ParameterAttribute\nSo, when I try to tell the <b>Stop-Process<\/b> cmdlet that I want to stop the Notepad process, it does not work because it recognizes that &ldquo;notepad&rdquo; is not a number, so we are not using the default parameter set. Also it is not using the <b>Name<\/b> parameter set because it does not accept the pipelined input. So, how can it work?\nThat is easy! Remove the word Notepad, and it works just fine. I know this will work because of the third parameter set, which accepts pipelined input:<\/p>\n<p style=\"margin-left:30px\">Parameter Set Name: InputObject<\/p>\n<p style=\"margin-left:30px\">Is default parameter set: False\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; Parameter Name: InputObject<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ParameterType = System.Diagnostics.Process[]<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Position = 0<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsMandatory = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; IsDynamic = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; HelpMessage =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipeline = True<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromPipelineByPropertyName = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; ValueFromRemainingArguments = False<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Aliases = {}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Attributes =<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Management.Automation.ParameterAttribute\nSo, all I need to do is to pipe a process object to the <b>Stop-Process<\/b> cmdlet, and it will stop that process. I can see what process it stops by using the <b>&ndash;PassThru<\/b> parameter, as shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:&gt; get-Process notepad | Stop-Process -PassThru\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212; &nbsp;&nbsp;&nbsp;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; 84&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8&nbsp;&nbsp;&nbsp;&nbsp; 1488&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8112&nbsp;&nbsp;&nbsp; 98&nbsp;&nbsp;&nbsp;&nbsp; 0.08&nbsp;&nbsp; 5412 notepad\nLR, that is all there is to using the pipeline. Poshpourri Week will continue tomorrow when I will talk about more cool stuff.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about piping the results from one cmdlet to another. &nbsp;Hey, Scripting Guy! I have a problem. When I pipe information from one Windows PowerShell cmdlet to anther (for example, when I use Get-Process and pipe it to Stop-Process ), sometimes it works, and sometimes it does not. This [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[51,149,3,45],"class_list":["post-1045","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-pipeline","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about piping the results from one cmdlet to another. &nbsp;Hey, Scripting Guy! I have a problem. When I pipe information from one Windows PowerShell cmdlet to anther (for example, when I use Get-Process and pipe it to Stop-Process ), sometimes it works, and sometimes it does not. This [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1045","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=1045"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1045\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=1045"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1045"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1045"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}