{"id":50993,"date":"2010-03-14T00:01:00","date_gmt":"2010-03-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/03\/14\/hey-scripting-guy-weekend-scripter-how-can-i-run-windows-powershell-commands-remotely\/"},"modified":"2010-03-14T00:01:00","modified_gmt":"2010-03-14T00:01:00","slug":"hey-scripting-guy-weekend-scripter-how-can-i-run-windows-powershell-commands-remotely","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-weekend-scripter-how-can-i-run-windows-powershell-commands-remotely\/","title":{"rendered":"Hey, Scripting Guy! Weekend Scripter: How Can I Run Windows PowerShell Commands Remotely?"},"content":{"rendered":"<p class=\"MsoNormal\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. It is Sunday evening in Charlotte, North Carolina, in the United States, which means it is Monday morning on the other side of the world. I was up late last night finishing yesterday&rsquo;s Weekend Scripter article. My good friend, Jit, found me on Office Communicator, and we chatted for a little while. He is my mentee, and I generally talk to him every month, but he has been gone for the holidays, so I missed talking to him. Not only is he extremely bright, but he had a wife who is an awesome cook and the consummate host. Jit lives in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Canberra\"><font face=\"Segoe\">Canberra, Australia<\/font><\/a>, which is a lovely town. Here is a photograph of the <a href=\"http:\/\/en.wikipedia.org\/wiki\/National_Museum_of_Australia\"><font face=\"Segoe\">National Museum of Australia<\/font><\/a> I took while in Canberra teaching a Windows PowerShell class.<\/p>\n<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Photograph of National Museum of Australia\" alt=\"Photograph of National Museum of Australia\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2010\/march\/hey0314\/wes-03-14-10-01.jpg\" width=\"600\" height=\"450\"><\/p>\n<p class=\"Fig-Graphic\">\n<p>&nbsp;<\/p>\n<\/p>\n<p class=\"MsoNormal\">The Scripting Wife came up to see who I was talking to and joined in our conversation. It was like a family reunion and lots of fun. When we were finished talking, the Scripting Wife looked at <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/03\/13\/hey-scripting-guy-march-13-2010.aspx\"><span>the Weekend Scripter article I had written<\/span><\/a>, and said, &ldquo;That is just about useless. How are they going to run those commands on remote computers?&rdquo; (<i>Scripting Editor<\/i>: The Scripting Wife is also responsible for mapping the human genome.)<\/p>\n<p class=\"MsoNormal\">If you wish to use the Environmental drive on a remote computer, you can use the <b>Invoke-Command<\/b> cmdlet in Windows PowerShell 2.0 (assuming you have enabled remoting) to easily retrieve the value. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Invoke-Command -computer win7-pc -ScriptBlock { $env:os }<br \/>Windows_NT<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">One thing to keep in mind with this technique is that if you mistype the environmental variable, you will not receive an error. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Invoke-Command -computer hyperv -ScriptBlock { $env:0s }<br \/>PS C:&gt; Invoke-Command -computer hyperv -ScriptBlock { $env:a }<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">When using WMI, it already has the ability to remote, assuming that it is not blocked via the firewall. To use the <b>Win32_Environment<\/b> WMI class against a remote computer, you only need to add the <b>&ndash;computername<\/b> parameter (or <b>&ndash;computer<\/b> for short) to the <b>Get-WMiObject<\/b> cmdlet. If you are remoting into an untrusted domain or are logged on using a low-rights account, use the <b>&ndash;credential<\/b> parameter. <\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Get-wmiobject win32_environment -computer win7-pc | where-object { $_.name -eq &#8216;os&#8217; }<\/p>\n<p>VariableValue<span>&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; <\/span>Name<span>&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; <\/span>UserName<br \/>&#8212;&#8212;&#8212;&#8212;-<span>&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; <\/span>&#8212;-<span>&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; <\/span>&#8212;&#8212;&#8211;<br \/>Windows_NT<span>&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; <\/span>OS<span>&nbsp;&nbsp; <\/span><span>&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;<\/span>&lt;SYSTEM&gt;<\/p>\n<p>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">To use the <b>wshEnvironment<\/b> object from the <b>wshShell<\/b> object, you will need to use a Windows PowerShell remote session. You can do this directly by using the <b>Enter-PSSession<\/b> cmdlet and supplying the name of the target computer. This is quick, but does not create a reusable session. When you exit the session, it ends. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Enter-PSSession -ComputerName win7-pc<br \/>[win7-pc]: PS C:UsersedDocuments&gt; $wshShell = New-Object -ComObject wscript.shell<br \/>[win7-pc]: PS C:UsersedDocuments&gt; $wshShell.Environment().item(&#8220;os&#8221;)<br \/>Windows_NT<br \/>[win7-pc]: PS C:UsersedDocuments&gt; exit<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Using the <b>ExpandEnvironmentStrings<\/b> method from the <b>WshShell<\/b> from inside a Windows PowerShell remote session would work exactly the same as using the <b>WshEnvironment<\/b> object just seen. If you really want to run the command on a single line<span>&mdash;<\/span>perhaps because you wanted to use the Task Scheduler<span>&mdash;<\/span>you would could do it as seen here. Keep in mind that thi\ns is a single line of code that would normally wrap. I added the line continuation marks, so the cut-and-paste command would work (if you change the target machine name), but normally I would not use line continuation here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Invoke-Command -ScriptBlock { (New-Object -ComObject `wscript.shell).ExpandEnvironmentStrings(&#8220;%os%&#8221;) } `<br \/>-ComputerName win7-pc<br \/>Windows_NT<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">You might think you could use <b>Invoke-Command<\/b> and perform the command prompt trick discussed yesterday, but that unfortunately does not work. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Invoke-Command -ScriptBlock { cmd ; set os ; exit } -computer win7-pc<br \/>Microsoft Windows [Version 6.1.7600]<br \/>Copyright (c) 2009 Microsoft Corporation.<span>&nbsp; <\/span>All rights reserved.<\/p>\n<p>C:UsersedDocuments&gt;<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">However, if you use the <b>Enter-PSSession<\/b> cmdlet, it still does not work. But, who cares, it was simply a trick anyway. No error is generated, it just does not work. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Enter-PSSession -ComputerName win7-pc<br \/>[win7-pc]: PS C:UsersedDocuments&gt; cmd<br \/>Microsoft Windows [Version 6.1.7600]<br \/>Copyright (c) 2009 Microsoft Corporation.<span>&nbsp; <\/span>All rights reserved.<\/p>\n<p>C:UsersedDocuments&gt;<br \/>[win7-pc]: PS C:UsersedDocuments&gt; set os<br \/>[win7-pc]: PS C:UsersedDocuments&gt; exit<br \/>PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Using the .NET Framework method to retrieve environmental variables is as simple as using <b>Invoke-Command<\/b>. Keep in mind that this would normally be a single-line command:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Invoke-Command -ComputerName win7-pc -ScriptBlock `<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">{ [environment]::GetEnvironmentVariable(&#8220;os&#8221;) }<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Windows_NT<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">If you were really working from the Windows PowerShell command line, you would probably want to use the alias for <b>Invoke-Command<\/b> (<b>icm<\/b>) and positional arguments. This shortens the typing and the command considerably, as seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt; Icm win7-pc { [environment]::GetEnvironmentVariable(&#8220;os&#8221;) }<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Windows_NT<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">PS C:&gt;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">As you can see, remoting commands with Windows PowerShell 2.0 is pretty easy, and normally will not involve much additional change to the way you work. <\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\"><font face=\"Segoe\">Twitter<\/font><\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\"><span><\/p>\n<p>&nbsp;<\/p>\n<p><\/span><\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p><b><span><\/span><\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. It is Sunday evening in Charlotte, North Carolina, in the United States, which means it is Monday morning on the other side of the world. I was up late last night finishing yesterday&rsquo;s Weekend Scripter article. My good friend, Jit, found me on Office Communicator, and we chatted [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,61,45],"class_list":["post-50993","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here. It is Sunday evening in Charlotte, North Carolina, in the United States, which means it is Monday morning on the other side of the world. I was up late last night finishing yesterday&rsquo;s Weekend Scripter article. My good friend, Jit, found me on Office Communicator, and we chatted [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50993","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=50993"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/50993\/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=50993"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=50993"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=50993"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}