{"id":8321,"date":"2007-03-06T23:40:00","date_gmt":"2007-03-06T23:40:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2007\/03\/06\/invoke-expression\/"},"modified":"2019-02-18T13:16:49","modified_gmt":"2019-02-18T20:16:49","slug":"invoke-expression","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/invoke-expression\/","title":{"rendered":"Invoke-Expression"},"content":{"rendered":"<p>I fixed a bug in Start-Demo (Script attached) that is worth exploring. The heart of Start-Demo is to get a line from file, display it and then run it showing the output. To do this I used Invoke-Expression (For simplicity sakes, I&#8217;m going to show you the code assuming that the line to execute is $LINE \u2013 the actual code is a bit more complicated) <\/p>\n<blockquote>\n<p><span>Invoke-Expression $($LINE + &#8221; | out-host&#8221;) <\/span><\/p>\n<\/blockquote>\n<p>We want to run the command and pipe it&#8217;s results to out-host. This &#8220;mostly&#8221; works. I noticed the failure as I started to do more complicated demos. I particular, I wanted to execute the following 2 lines: <\/p>\n<p><span>$y = Get-Process<br \/>$y | where {$_.handles \u2013ge 500} |sort handles <\/span><\/p>\n<p>When I ran the first command, it output the processes and it didn&#8217;t assign anything to $y (can you guess why?). What was actually getting executed was: <\/p>\n<blockquote>\n<p><span>$y = Get-Process | Out-Host <\/span><\/p>\n<\/blockquote>\n<p>&#8220;Out-Host&#8221; took precedence over the &#8220;=&#8221; so the objects were getting printed on the host and nothing came out of the pipeline so $y was set to $NULL. S <\/p>\n<p>From there I realized that I should run this in a script block and then pipe the results to &#8220;out-host&#8221;. So I changed the code to be: <\/p>\n<blockquote>\n<p><span><span>Invoke-Expression $(<\/span><span><strong>&#8220;&amp;{ &#8221; <\/strong><\/span><span>+ $LINE + &#8220;<\/span><span><strong>}<\/strong><\/span><span> | out-host&#8221;) <\/span><\/span><\/p>\n<\/blockquote>\n<p>What do you think? Should that work or not? <\/p>\n<p>Well, the first like worked a treat. It ran but did not output the process objects. Success right? Wrong! The second command didn&#8217;t work. What happens is that when you run code inside &amp;{}, it creates a new SCOPE for variables and runs the command in that scope. So when you run: <\/p>\n<p><span>&nbsp;&nbsp;&nbsp;&nbsp;&amp;{$y = Get-Process} | out-host <\/span><\/p>\n<p>It runs Get-Process, assigns the objects to a local variable $Y and then exits the scope \u2013 which throws away the local variable. So then when you try to run <\/p>\n<blockquote>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;<span>$y | where {$_.handles \u2013ge 500} |sort handles <\/span><\/p>\n<\/blockquote>\n<p>$y is null so you are out of luck. With a lesser language, you&#8217;d be hosed right now but with PowerShell, we thought of these things (even if I forgot it when I wrote this script!). So how does PowerShell help? (You&#8217;ll want to put your seatbelts on for this\u2026.) You can dot-source scriptblocks! <\/p>\n<p>Yup. Just as you can run a script or dot-source a script, you can run a scriptblock or dot-source it. When you run (either of these), it creates a new variable scope, executes the code, and throws away the variable scope eliminating any of the variables that were used. When you dot-source these, it runs in the current scope so any changes to variables persist after the code executes. So what is the syntax for dot-sourcing a scriptblock? <\/p>\n<blockquote>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;<span>.{} <\/span><\/p>\n<\/blockquote>\n<p>Of course. <\/p>\n<p><span>PS&gt; .{$y = Get-Process} | out-host<br \/>PS&gt; .{$y |where {$_.handles -ge 500} |sort handles} | out-host<\/p>\n<p>Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName<br \/>&#8212;&#8212;- &#8212;&#8212; &#8212;&#8211; &#8212;&#8211; &#8212;&#8211; &#8212;&#8212; &#8212; &#8212;&#8212;&#8212;&#8211;<br \/>510 14 18460 11640 89 10.67 940 svchost<br \/>571 18 12020 13152 98 7.81 3824 taskeng<br \/>641 26 35008 42644 176 117.69 2968 wmplayer<br \/>648 11 5832 20856 188 28.31 512 csrss<br \/>659 0 0 4592 9 4 System<br \/>659 26 29248 44148 212 45.89 1900 explorer<br \/>661 27 29812 25984 172 4.27 4268 iexplore<br \/>674 6 1708 4240 88 4.53 456 csrss<br \/>724 14 13284 15232 95 11.38 2416 CcmExec<br \/>726 14 47232 37604 213 15.48 4020 powershell<br \/>751 18 81692 81848 196 440.50 1044 svchost<br \/>765 32 11680 15452 98 34.89 1180 svchost<br \/>778 4 3024 3020 40 0.05 504 psxss<br \/>1026 29 19456 16192 124 36.36 1376 svchost<br \/>1047 33 47800 41620 293 42.59 2664 communicator<br \/>1371 14 63896 29548 229 145.56 2184 SearchIndexer<br \/>1433 19 7136 5060 57 25.31 588 lsass<br \/>1796 52 159108 96184 441 158.30 4620 iexplore<br \/>1890 50 37040 38284 157 127.00 1060 svchost<br \/>5661 83 159676 149736 781 370.58 1128 OUTLOOK<br \/><\/span><\/p>\n<p>So the correct code in the script should have been: <\/p>\n<blockquote>\n<p><span><span>Invoke-Expression $(&#8220;<\/span><span>.{ <\/span><span>&#8221; + $LINE + &#8220;<\/span><span><strong>}<\/strong><\/span><span> | out-host&#8221;) <\/span><\/span><\/p>\n<\/blockquote>\n<p>Enjoy! <\/p>\n<p>Jeffrey Snover [MSFT]<br \/>Windows PowerShell\/MMC Architect<br \/>Visit the Windows PowerShell Team blog at: <a href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/a><br \/>Visit the Windows PowerShell ScriptCenter at: <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx\">http:\/\/www.microsoft.com\/technet\/scriptcenter\/hubs\/msh.mspx<\/a> <\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/01\/82\/45\/09\/start-demo.ps1\">start-demo.ps1<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I fixed a bug in Start-Demo (Script attached) that is worth exploring. The heart of Start-Demo is to get a line from file, display it and then run it showing the output. To do this I used Invoke-Expression (For simplicity sakes, I&#8217;m going to show you the code assuming that the line to execute is [&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":[],"class_list":["post-8321","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"blog_post_summary":"<p>I fixed a bug in Start-Demo (Script attached) that is worth exploring. The heart of Start-Demo is to get a line from file, display it and then run it showing the output. To do this I used Invoke-Expression (For simplicity sakes, I&#8217;m going to show you the code assuming that the line to execute is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/8321","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=8321"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/8321\/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=8321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=8321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=8321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}