{"id":6611,"date":"2008-02-29T13:13:41","date_gmt":"2008-02-29T13:13:41","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2008\/02\/29\/remoting-using-powershell-v1\/"},"modified":"2019-02-18T13:16:10","modified_gmt":"2019-02-18T20:16:10","slug":"remoting-using-powershell-v1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/remoting-using-powershell-v1\/","title":{"rendered":"Remoting Using PowerShell V1"},"content":{"rendered":"<p>As you probably know by now, &quot;remoting&quot; is one of the cornerstone features of the next version of PowerShell.&#160; I am absolutely thrilled with the stuff we are doing here and the benefits that come from that approach.&#160; That said, there are lots of things that need to be buttoned up before this is ready: the right user experience, proper serialization, where and how much throttling to do, how to maximize bandwidth utilization and of course our primary concern: how to make remoting safe and secure.&#160; We are working closing with some of the companies top security people reviewing what we are doing to ensure that we do it right.&#160; (Last week we were in a conference room with about 20 people walking through our scenarios.&#160; It became very clear to me that Microsoft&#8217;s investments and prioritization in security had really paid off as these folks were just awesome.)<\/p>\n<p>So the bottom line is that while I&#8217;m optimistic about the remoting, the reality is that is going to take a while before it is cooked.&#160; If I was an IT Pro, I can imagine saying something to the effect of, &quot;That is fine but my hair is on fire &#8211; what can I do NOW?&quot;<\/p>\n<p>The answer to that is:&#160; <font size=\"4\">Cheat<\/font>.<\/p>\n<p>&#160;<\/p>\n<p>Yup &#8211; you can do PowerShell remoting with V1.&#160; It&#8217;s not going to be pretty but it can be done and hey &#8211; when your hair is on fire, you&#8217;ll stick your head in a bucket of #$@! to put it out right?&#160; (this approach isn&#8217;t a bucket of @#%!, I just wanted to use that phrase :-))<\/p>\n<p>Let&#8217;s walk through the basics and then compose them into a solution.<\/p>\n<p>Type &quot;Powershell -?&quot; and you&#8217;ll see the command line parameters you can use to start PowerShell.&#160; There are a couple that are interesting here.&#160; Notice that there is a -Command parameter.&#160; Give it a try by typing <\/p>\n<p><font face=\"Courier New\" size=\"2\">Powershell -Command Get-Process *ss<\/font><\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>You might notice a bunch of cruft before the output, this is&#160; because we are running your profile and that might generate output.&#160; We say -NoProfile to stop that.&#160; We&#8217;ll also add -NonInteractive so that we don&#8217;t get prompted for any input.&#160; So now try<\/p>\n<p><font face=\"Courier New\" size=\"2\">PowerShell -NoProfile -NonInteractive -Command Get-Process *ss<\/font><\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>If you plan with this for more than a little bit, you are going to find that you want to run a command that requires a ton of escaping and quoting to work properly (think through a pipeline &#8211; it could happen in either process).&#160; <\/p>\n<p><font face=\"Courier New\" size=\"2\">PowerShell -NoProfile -NonInteractive -Command &quot;Get-Process *ss |sort handles&quot;<\/font><\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>What you will find is that at some point, the escaping can become incomprehensible.&#160; That&#8217;s where the hidden parameter comes in.&#160; I don&#8217;t know why we decided not to document this or who made that decision but we have a -EncodedCommand parameter that does not show up in our help (I suspect it&#8217;s because we would have to explain how to encode it and people felt that most people would be too confused by this [you&#8217;ll see what I mean] and therefore documenting it would do more harm than good.)&#160; I blogged this parameter a while ago <a href=\"http:\/\/blogs.msdn.com\/powershell\/archive\/2006\/05\/07\/592045.aspx\">HERE<\/a>.<\/p>\n<p>Here is how you take a scriptblock, turn it into string and then encode it and invoke it:<\/p>\n<p><font face=\"Courier New\" size=\"2\">$script = {gps |where {$_.handles -ge 900}|sort handles}.ToString()&#160; <br \/>$encodedScript = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($script))       <br \/>PowerShell -NoProfile -NonInteractive -EncodedCommand $encodedScript<\/font><\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>Now it is time to remote it! <\/p>\n<p>WINRS is a commandline interface to invoke a command on a remote machine via WS-MGMT.&#160; You can now run this remotely by doing the following:<\/p>\n<p><font face=\"Courier New\" size=\"2\">Winrs &quot;-r:localhost&quot; PowerShell -NoProfile -NonInteractive -EncodedCommand $encodedScript<\/font><\/p>\n<p>And there you have it REMOTING using PowerShell V1.&#160;&#160; (Notice that WINRS allows you to specify UserName and Password as well)<\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>Not it is time to put a bow on it and go to hit the gym.<\/p>\n<p><font face=\"Courier New\" size=\"2\">function Invoke-RemoteCommand      <br \/>{       <br \/>param(       <br \/>$ComputerName,       <br \/>[SCRIPTBLOCK]$script       <br \/>)       <br \/>&#160;&#160;&#160; $encodedScript = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($script))       <br \/>&#160;&#160;&#160; Winrs &quot;-r:$ComputerName&quot; PowerShell -NoProfile -NonInteractive -EncodedCommand $encodedScript       <br \/>} <\/font><\/p>\n<p><font face=\"Courier New\" size=\"2\">Invoke-RemoteCommand localhost {gps |where {$_.handles -ge 500} |sort handles}<\/font><\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>It&#8217;s a beautiful thing!&#160; Oh wait a minute.&#160; That almost works but not really.&#160; Try this and look what happens when you try to do the filtering and sorting locally:<\/p>\n<p><font face=\"Courier New\" size=\"2\">Invoke-RemoteCommand localhost {gps} |where {$_.handles -ge 500} |sort handles<\/font><\/p>\n<p>Complete crap.<\/p>\n<p>&#160;<\/p>\n<p>&#160;<\/p>\n<p>If only there was a way I could get objects back instead of text.&#160; That&#8217;s sorta the point of PowerShell right?&#160; Hmmm, if you go back to the beginning and look at the parameters you can provide PowerShell, you&#8217;ll see -OutputFormat and that can take the value &quot;XML&quot;.&#160; This will produce CLIXML and PowerShell native command processor (the thing that invokes processes) looks at the output of a command for something we call a STRUCTURED DataStream and autoconverts that datastream into objects.&#160; Thus the final script looks like this:<\/p>\n<p><font face=\"Courier New\" size=\"2\">function Invoke-RemoteCommand      <br \/>{       <br \/>param(       <br \/>$ComputerName,       <br \/>[SCRIPTBLOCK]$script       <br \/>)       <br \/>&#160;&#160;&#160; $encodedScript = [System.Convert]::ToBase64String([System.Text.Encoding]::UNICODE.GetBytes($script))       <br \/>&#160;&#160;&#160; $objects = Winrs &quot;-r:$ComputerName&quot; PowerShell -OutputFormat XML -NoProfile -NonInteractive -EncodedCommand $encodedScript       <br \/>&#160;&#160;&#160; Write-Output $objects       <br \/>} <\/font><\/p>\n<p><font face=\"Courier New\" size=\"2\">Invoke-RemoteCommand localhost {gps} |where {$_.handles -ge 500} |sort handles<\/font><\/p>\n<p>Now it&#8217;s time to hit the gym.&#160; <\/p>\n<p>Enjoy!<\/p>\n<p>&#160;<\/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","protected":false},"excerpt":{"rendered":"<p>As you probably know by now, &quot;remoting&quot; is one of the cornerstone features of the next version of PowerShell.&#160; I am absolutely thrilled with the stuff we are doing here and the benefits that come from that approach.&#160; That said, there are lots of things that need to be buttoned up before this is ready: [&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":[8],"class_list":["post-6611","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-remoting"],"acf":[],"blog_post_summary":"<p>As you probably know by now, &quot;remoting&quot; is one of the cornerstone features of the next version of PowerShell.&#160; I am absolutely thrilled with the stuff we are doing here and the benefits that come from that approach.&#160; That said, there are lots of things that need to be buttoned up before this is ready: [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6611","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=6611"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/6611\/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=6611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=6611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=6611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}