{"id":10351,"date":"2006-05-07T18:35:00","date_gmt":"2006-05-07T18:35:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2006\/05\/07\/invoking-powershell-with-complex-expressions-using-scriptblocks\/"},"modified":"2019-02-18T13:21:44","modified_gmt":"2019-02-18T20:21:44","slug":"invoking-powershell-with-complex-expressions-using-scriptblocks","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/invoking-powershell-with-complex-expressions-using-scriptblocks\/","title":{"rendered":"Invoking PowerShell with complex expressions using Scriptblocks"},"content":{"rendered":"<p>&lt;WIZARD WARNING&gt;<\/p>\n<p>First a reminder:&nbsp; when you are in PowerShell (formerly knows as Monad), you can run anything you want out-of-process using the construct:<\/p>\n<p><font face=\"Courier New\"><strong>PowerShell {Scriptblock}<\/strong><\/font><\/p>\n<p>The great example of this is <\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; #RUN EVERYTHING IN PROCESS<br \/>PS&gt; <strong>get-process |where {$_.handles -ge 900} |sort handles<\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">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<br \/>&#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;<br \/>&nbsp;&nbsp; 1369&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 45&nbsp;&nbsp;&nbsp; 55328&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16880&nbsp;&nbsp; 469&nbsp;&nbsp;&nbsp; 81.67&nbsp;&nbsp; 3056 OUTLOOK<br \/>&nbsp;&nbsp; 1575&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48&nbsp;&nbsp;&nbsp; 84616&nbsp;&nbsp;&nbsp;&nbsp; 116200&nbsp;&nbsp; 450&nbsp;&nbsp; 103.52&nbsp;&nbsp; 3212 iexplore<br \/>&nbsp;&nbsp; 2367&nbsp;&nbsp;&nbsp;&nbsp; 190&nbsp;&nbsp;&nbsp; 31192&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40676&nbsp;&nbsp; 152&nbsp;&nbsp; 179.70&nbsp;&nbsp; 1768 svchost<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; #RUN EVERYTHING OUT OF PROCESS<br \/>PS&gt; <strong>PowerShell <font color=\"#ff0000\" size=\"2\">{<\/font>get-process |where {$_.handles -ge 900} |sort handles<font color=\"#ff0000\" size=\"2\">}<\/font><\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">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<br \/>&#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;<br \/>&nbsp;&nbsp; 1369&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 45&nbsp;&nbsp;&nbsp; 55328&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16880&nbsp;&nbsp; 469&nbsp;&nbsp;&nbsp; 81.73&nbsp;&nbsp; 3056 OUTLOOK<br \/>&nbsp;&nbsp; 1575&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48&nbsp;&nbsp;&nbsp; 84616&nbsp;&nbsp;&nbsp;&nbsp; 116200&nbsp;&nbsp; 450&nbsp;&nbsp; 103.56&nbsp;&nbsp; 3212 iexplore<br \/>&nbsp;&nbsp; 2369&nbsp;&nbsp;&nbsp;&nbsp; 190&nbsp;&nbsp;&nbsp; 31192&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40676&nbsp;&nbsp; 152&nbsp;&nbsp; 179.73&nbsp;&nbsp; 1768 svchost<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; #RUN the first 2 elements of the pipeline in process and the last in-process<br \/>PS&gt; <strong>PowerShell <font color=\"#ff0000\" size=\"2\">{<\/font>get-process |where {$_.handles -ge 900}<font color=\"#ff0000\" size=\"2\">}<\/font> |sort handles<\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">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<br \/>&#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;<br \/>&nbsp;&nbsp; 1369&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 45&nbsp;&nbsp;&nbsp; 55328&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16880&nbsp;&nbsp; 469&nbsp;&nbsp;&nbsp; 81.75&nbsp;&nbsp; 3056 OUTLOOK<br \/>&nbsp;&nbsp; 1571&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48&nbsp;&nbsp;&nbsp; 84768&nbsp;&nbsp;&nbsp;&nbsp; 116352&nbsp;&nbsp; 450&nbsp;&nbsp; 103.59&nbsp;&nbsp; 3212 iexplore<br \/>&nbsp;&nbsp; 2373&nbsp;&nbsp;&nbsp;&nbsp; 190&nbsp;&nbsp;&nbsp; 30716&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40220&nbsp;&nbsp; 152&nbsp;&nbsp; 179.81&nbsp;&nbsp; 1768 svchost<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; #RUN the first element of the pipeline in process and the last 2 in-process<br \/>PS&gt; <strong>PowerShell <font color=\"#ff0000\" size=\"2\">{<\/font>get-process<font color=\"#ff0000\" size=\"2\">}<\/font> |where {$_.handles -ge 900} |sort handles<\/strong><\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\">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<br \/>&#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;<br \/>&nbsp;&nbsp; 1369&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 45&nbsp;&nbsp;&nbsp; 55328&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 16948&nbsp;&nbsp; 469&nbsp;&nbsp;&nbsp; 81.80&nbsp;&nbsp; 3056 OUTLOOK<br \/>&nbsp;&nbsp; 1567&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48&nbsp;&nbsp;&nbsp; 84252&nbsp;&nbsp;&nbsp;&nbsp; 115892&nbsp;&nbsp; 449&nbsp;&nbsp; 103.63&nbsp;&nbsp; 3212 iexplore<br \/>&nbsp;&nbsp; 2398&nbsp;&nbsp;&nbsp;&nbsp; 190&nbsp;&nbsp;&nbsp; 31292&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40724&nbsp;&nbsp; 153&nbsp;&nbsp; 180.02&nbsp;&nbsp; 1768 svchost<br \/><\/font><\/p>\n<p>Now &#8211; have you ever tried to do that from CMD.EXE?<\/p>\n<p><font face=\"Courier New\" color=\"#000080\" size=\"1\">C:\\&gt;powershell {get-process |where {$_.handles -ge 900} | Sort Handles }<br \/>&#8216;where&#8217; is not recognized as an internal or external command,<br \/>operable program or batch file.<\/font><\/p>\n<p>That doesn&#8217;t work so well.&nbsp; You try a number of things and depending upon what you are trying to do, that will work better or worse.&nbsp; If you want to execute script blocks with single and double quotes, this becomes incomprehensible pretty quickly.&nbsp; <\/p>\n<p>The problem is that there are various components which try to &#8220;help&#8221; you by processing the arguments&nbsp;(e.g. stripping off quotes).&nbsp; The reason this ALWAYS works when you invoke it from Powershell is &#8230; we cheat.&nbsp;&nbsp; Well, we cheat in a Kabayashi Maru sort of way (See Kirk&#8217;s solution <a href=\"http:\/\/en.wikipedia.org\/wiki\/Kobayashi_Maru\">http:\/\/en.wikipedia.org\/wiki\/Kobayashi_Maru<\/a>).&nbsp; <\/p>\n<p>Here is a trick that you can use to see what is going on.&nbsp; The system type [ENVIRONMENT] has lots of great static properties:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; [Environment] |gm -static -membertype property<\/font><\/p>\n<p><font face=\"Courier New\" size=\"1\"><\/p>\n<p>&nbsp;&nbsp; TypeName: System.Environment<\/p>\n<p>Name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MemberType Definition<br \/>&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-<br \/>CommandLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String CommandLine {get;}<br \/>CurrentDirectory&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String CurrentDirectory {get&#8230;<br \/>ExitCode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Int32 ExitCode {get;set;}<br \/>HasShutdownStarted Property&nbsp;&nbsp; static System.Boolean HasShutdownStarted {&#8230;<br \/>MachineName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String MachineName {get;}<br \/>NewLine&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String NewLine {get;}<br \/>OSVersion&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.OperatingSystem OSVersion {g&#8230;<br \/>ProcessorCount&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Int32 ProcessorCount {get;}<br \/>StackTrace&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String StackTrace {get;}<br \/>SystemDirectory&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String SystemDirectory {get;}<br \/>TickCount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Int32 TickCount {get;}<br \/>UserDomainName&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String UserDomainName {get;}<br \/>UserInteractive&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Boolean UserInteractive {get;}<br \/>UserName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.String UserName {get;}<br \/>Version&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Version Version {get;}<br \/>WorkingSet&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Property&nbsp;&nbsp; static System.Int64 WorkingSet {get;}<\/font><\/p>\n<p>Including the commandline used to execute the current process.<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; [Environment]::commandline<br \/>&#8220;C:\\Program Files\\Windows PowerShell\\v1.0\\powershell.exe&#8221;<\/font><\/p>\n<p>From there, you can do the following to see our cheat:<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; PowerShell {[Environment]::CommandLine}<br \/>&#8220;C:\\Program Files\\Windows PowerShell\\v1.0\\powershell.exe&#8221; -encodedCommand WwBFAG4AdgBpAHIAbwBuAG0AZQBuAHQAXQA6ADoAQwBvAG0AbQBhAG4AZABMAGkAbgBlAA== -inputFormat xml -outputFormat xml<\/font><\/p>\n<p>When we launch an external process which has a parameter with {}&#8217;s we say that that is a subshell and we TWEAK the command invocation by&nbsp;Base64 encoding the scriptblock and by telling the command to consume and produce XML.<\/p>\n<p>If you ever need to&nbsp;invoke a&nbsp;complex piece of code directly from CMD.exe&nbsp;you can run PowerShell and&nbsp;do the following to get the string to pass to -EncodedCommand :<\/p>\n<p><font face=\"Courier New\" size=\"1\">PS&gt; $script = {gps |where {$_.handles -ge 900}|sort handles}.ToString()<br \/>PS&gt; [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetByte<br \/>s($script))<br \/>ZwBwAHMAIAB8AHcAaABlAHIAZQAgAHsAJABfAC4AaABhAG4AZABsAGUAcwAgAC0AZwBlACAAOQA<br \/>wADAAfQB8AHMAbwByAHQAIABoAGEAbgBkAGwAZQBzAA==<\/font><\/p>\n<p>You can then use that string from CMD.EXE:<\/p>\n<p><font face=\"Courier New\" color=\"#000080\" size=\"1\">C:\\&gt;PowerShell -EncodedCommand ZwBwAHMAIAB8AHcAaABlAHIAZQAgAHsAJABfAC4AaABhAG4AZ<br \/>ABsAGUAcwAgAC0AZwBlACAAOQAwADAAfQB8AHMAbwByAHQAIABoAGEAbgBkAGwAZQBzAA==<\/font><\/p>\n<p><font face=\"Courier New\" color=\"#000080\" size=\"1\">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<br \/>&#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;<br \/>&nbsp;&nbsp; 1366&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 45&nbsp;&nbsp;&nbsp; 55328&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 21552&nbsp;&nbsp; 469&nbsp;&nbsp;&nbsp; 83.50&nbsp;&nbsp; 3056 OUTLOOK<br \/>&nbsp;&nbsp; 1665&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 48&nbsp;&nbsp;&nbsp; 90164&nbsp;&nbsp;&nbsp;&nbsp; 122736&nbsp;&nbsp; 466&nbsp;&nbsp; 276.13&nbsp;&nbsp; 3212 iexplore<br \/>&nbsp;&nbsp; 2396&nbsp;&nbsp;&nbsp;&nbsp; 202&nbsp;&nbsp;&nbsp; 31036&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 40664&nbsp;&nbsp; 153&nbsp;&nbsp; 192.08&nbsp;&nbsp; 1768 svchost<br \/><\/font><\/p>\n<p>Enjoy!<br \/>Jeffrey Snover [MSFT]<br \/>Windows PowerShell Architect<\/p>\n<p><font face=\"Courier New\" size=\"1\"><\/font>&nbsp;<\/p>\n<p><font face=\"Courier New\" size=\"1\">PSMDTAG:FAQ: What is the -EncodedCommand parameter on PowerShell.Exe for?<br \/>PSMDTAG:FAQ: How can I see the command line that started the PowerShell process?<br \/>PSMDTAG:FAQ:&nbsp;How do I run a scriptblock in a seperate process?<br \/>PSMDTAG:INTERNAL:&nbsp;avoiding funky&nbsp;syntax across process invocations, Base64 encoding of ENCODEDCOMMAND<br \/><\/font><font face=\"Courier New\" size=\"1\"><\/p>\n<p><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&lt;WIZARD WARNING&gt; First a reminder:&nbsp; when you are in PowerShell (formerly knows as Monad), you can run anything you want out-of-process using the construct: PowerShell {Scriptblock} The great example of this is PS&gt; #RUN EVERYTHING IN PROCESSPS&gt; get-process |where {$_.handles -ge 900} |sort handles 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&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[10,19],"class_list":["post-10351","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-faq","tag-internal"],"acf":[],"blog_post_summary":"<p>&lt;WIZARD WARNING&gt; First a reminder:&nbsp; when you are in PowerShell (formerly knows as Monad), you can run anything you want out-of-process using the construct: PowerShell {Scriptblock} The great example of this is PS&gt; #RUN EVERYTHING IN PROCESSPS&gt; get-process |where {$_.handles -ge 900} |sort handles 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&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10351","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=10351"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/10351\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=10351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=10351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=10351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}