{"id":5861,"date":"2008-06-19T08:34:00","date_gmt":"2008-06-19T08:34:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2008\/06\/19\/push-noun\/"},"modified":"2019-02-18T13:13:10","modified_gmt":"2019-02-18T20:13:10","slug":"push-noun","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/push-noun\/","title":{"rendered":"Push-Noun"},"content":{"rendered":"<p>We looked at a lot of CLI models when designing PowerShell.&#160; One of them was netsh.&#160; One of the things I had a love\/hate relationship with was netsh&#8217;s use of context.&#160; In netsh, you can set context via navigation and then you don&#8217;t need to provide that context on the command line.&#160; For instance you navigate into the FIREWALL and then you perform a set of operations and you don&#8217;t need to say that you are working on the firewall because it picks it up from the context.<\/p>\n<p>I thought I would experiment with this a little this morning.&#160; I don&#8217;t know if this is useful or not but it shows a couple of interesting scripting techniques so I thought I would share it anyway.&#160; This is PUSH-NOUN.PS1.&#160; You can push a NOUN context and then you don&#8217;t need to specify that noun for the first command in a command sequence &#8211; you just specify the verb.&#160; You type &quot;?&quot; for help,&#160; &quot;exit&quot; to exit and &quot;! cmd&quot; to escape and execute a command directly.&#160; The examples will make it more clear.&#160; <\/p>\n<p>First the code:<\/p>\n<p><font face=\"Consolas\" size=\"2\"># Push-Noun.ps1     <br \/># Sets a context which allows you to work on a noun similar to the way NETSH does      <br \/># WORKS WITH V1<\/font><font face=\"Consolas\" size=\"2\">     <br \/>param($noun)      <br \/>while ($true)      <br \/>{      <br \/>&#160;&#160;&#160; Write-Host &quot;[$Noun]&gt; &quot; -NoNewLine      <br \/>&#160;&#160;&#160; $line = $host.UI.ReadLine().trim()      <br \/>&#160;&#160;&#160; switch ($line)      <br \/>&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160; &quot;exit&quot;&#160;&#160; {return}      <br \/>&#160;&#160;&#160; &quot;quit&quot;&#160;&#160; {return}      <br \/>&#160;&#160;&#160; &quot;?&quot;&#160;&#160;&#160;&#160;&#160; {Get-Command &quot;*-$Noun&quot; |ft Verb,Definition -Auto |out-host}      <br \/>&#160;&#160;&#160; {$_.StartsWith(&quot;!&quot;)}      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $Cmd = $_.SubString(1)      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Invoke-Expression $cmd |out-host      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; default&#160; {      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $Verb,$args = $Line.Split()      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $Cmd = &quot;$verb-$Noun $args&quot;      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Invoke-Expression $cmd |out-host      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }      <br \/>&#160;&#160;&#160; }      <br \/>}<\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\"><\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">Now let&#8217;s run it:<\/font>    <\/p>\n<p><\/p>\n<\/p>\n<p><font face=\"Consolas\" size=\"2\">PS&gt;<strong> .\\push-noun service<\/strong>      <br \/>[service]&gt; <strong>?<\/strong><\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">Verb&#160;&#160;&#160; Definition     <br \/>&#8212;-&#160;&#160;&#160; &#8212;&#8212;&#8212;-      <br \/>Get&#160;&#160;&#160;&#160; Get-Service [[-Name] &lt;String[]&gt;] [-ComputerName &lt;String[]&gt;] [-Include &lt;String      <br \/>New&#160;&#160;&#160;&#160; New-Service [-Name] &lt;String&gt; [-BinaryPathName] &lt;String&gt; [-DisplayName &lt;String      <br \/>Restart Restart-Service [-Name] &lt;String[]&gt; [-Force] [-PassThru] [-Include &lt;String[]&gt;]      <br \/>Resume&#160; Resume-Service [-Name] &lt;String[]&gt; [-PassThru] [-Include &lt;String[]&gt;] [-Exclude      <br \/>Set&#160;&#160;&#160;&#160; Set-Service [-Name] &lt;String&gt; [-DisplayName &lt;String&gt;] [-Description &lt;String&gt;]      <br \/>Start&#160;&#160; Start-Service [-Name] &lt;String[]&gt; [-PassThru] [-Include &lt;String[]&gt;] [-Exclude       <br \/>Stop&#160;&#160;&#160; Stop-Service [-Name] &lt;String[]&gt; [-Force] [-PassThru] [-Include &lt;String[]&gt;]       <br \/>Suspend Suspend-Service [-Name] &lt;String[]&gt; [-PassThru] [-Include &lt;String[]&gt;] <\/font><\/p>\n<p><font size=\"2\"><font face=\"Consolas\">[service]&gt; <strong>get a*<\/strong><\/font><\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">Status&#160;&#160; Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DisplayName     <br \/>&#8212;&#8212;&#160;&#160; &#8212;-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8211;      <br \/>Running&#160; AeLookupSvc&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application Experience      <br \/>Running&#160; ALG&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application Layer Gateway Service      <br \/>Stopped&#160; Appinfo&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application Information      <br \/>Running&#160; AppMgmt&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application Management      <br \/>Running&#160; AudioEndpointBu&#8230; Windows Audio Endpoint Builder      <br \/>Running&#160; Audiosrv&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Windows Audio<\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">[service]&gt; <\/font><font size=\"2\"><font face=\"Consolas\"><strong>get |where {$_.name -match &quot;^A&quot; -AND $_.Status -eq &quot;stopped&quot;}         <br \/><\/strong>Status&#160;&#160; Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; DisplayName        <br \/>&#8212;&#8212;&#160;&#160; &#8212;-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;&#8211;        <br \/>Stopped&#160; Appinfo&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Application Information<\/font><\/font><\/p>\n<p><font size=\"2\"><font face=\"Consolas\">[service]&gt;<strong> !gps *ss<\/strong><\/font><\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">Handles&#160; NPM(K)&#160;&#160;&#160; PM(K)&#160;&#160;&#160;&#160;&#160; WS(K) VM(M)&#160;&#160; CPU(s)&#160;&#160;&#160;&#160; Id ProcessName     <br \/>&#8212;&#8212;-&#160; &#8212;&#8212;&#160;&#160;&#160; &#8212;&#8211;&#160;&#160;&#160;&#160;&#160; &#8212;&#8211; &#8212;&#8211;&#160;&#160; &#8212;&#8212;&#160;&#160;&#160;&#160; &#8212; &#8212;&#8212;&#8212;&#8211;      <br \/>&#160;&#160;&#160; 673&#160;&#160;&#160;&#160;&#160;&#160; 8&#160;&#160;&#160;&#160; 2308&#160;&#160;&#160;&#160;&#160;&#160; 6636&#160;&#160;&#160; 70&#160;&#160;&#160;&#160; 6.75&#160;&#160;&#160; 492 csrss      <br \/>&#160;&#160;&#160; 539&#160;&#160;&#160;&#160;&#160;&#160; 7&#160;&#160;&#160; 16044&#160;&#160;&#160;&#160;&#160; 21460&#160;&#160; 190&#160;&#160; 149.98&#160;&#160;&#160; 540 csrss      <br \/>&#160;&#160; 1633&#160;&#160;&#160;&#160;&#160; 16&#160;&#160;&#160; 11040&#160;&#160;&#160;&#160;&#160; 17680&#160;&#160;&#160; 68&#160;&#160;&#160; 67.47&#160;&#160;&#160; 656 lsass      <br \/>&#160;&#160;&#160; 866&#160;&#160;&#160;&#160;&#160;&#160; 5&#160;&#160;&#160;&#160; 3976&#160;&#160;&#160;&#160;&#160;&#160; 5720&#160;&#160;&#160; 33&#160;&#160;&#160;&#160; 2.56&#160;&#160;&#160; 548 psxss      <br \/>&#160;&#160;&#160;&#160; 33&#160;&#160;&#160;&#160;&#160;&#160; 1&#160;&#160;&#160;&#160;&#160; 312&#160;&#160;&#160;&#160;&#160;&#160;&#160; 760&#160;&#160;&#160;&#160; 5&#160;&#160;&#160;&#160; 0.08&#160;&#160;&#160; 428 smss<\/font><\/p>\n<p><font face=\"Consolas\" size=\"2\">[service]&gt; exit     <br \/>PS&gt;<\/font><\/p>\n<p>Note that given the mechanisms we have, this only really works with the first command in the sequence.&#160; Image that you wanted to do something like:<\/p>\n<p>PS&gt; Get | where {$_.name -match $test} |STOP<\/p>\n<p>Where STOP did not have to specify the NOUN.&#160; You really can&#8217;t do that today.&#160; We have been thinking about exposing a TOKEN-NOT-RESOLVED event which would call a user-defined function which would allow you to do runtime fixups.&#160; If we had that mechanism in place, you could do this.&#160;&#160; Hmmmmmm.<\/p>\n<p>Enjoy!<\/p>\n<p>Jeffrey Snover [MSFT]   <br \/>Windows Management Partner Architect    <br \/>Visit the Windows PowerShell Team blog at:&#160;&#160;&#160; <a href=\"http:\/\/blogs.msdn.com\/PowerShell\">http:\/\/blogs.msdn.com\/PowerShell<\/a>    <br \/>Visit the Windows PowerShell ScriptCenter at:&#160; <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\/08\/62\/15\/15\/push-noun.ps1\">push-noun.ps1<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We looked at a lot of CLI models when designing PowerShell.&#160; One of them was netsh.&#160; One of the things I had a love\/hate relationship with was netsh&#8217;s use of context.&#160; In netsh, you can set context via navigation and then you don&#8217;t need to provide that context on the command line.&#160; For instance you [&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":[285],"class_list":["post-5861","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-push-noun"],"acf":[],"blog_post_summary":"<p>We looked at a lot of CLI models when designing PowerShell.&#160; One of them was netsh.&#160; One of the things I had a love\/hate relationship with was netsh&#8217;s use of context.&#160; In netsh, you can set context via navigation and then you don&#8217;t need to provide that context on the command line.&#160; For instance you [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/5861","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=5861"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/5861\/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=5861"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=5861"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=5861"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}