{"id":13641,"date":"2011-06-13T00:01:00","date_gmt":"2011-06-13T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/06\/13\/use-powershell-invoke-command-for-remoting\/"},"modified":"2022-06-10T09:42:04","modified_gmt":"2022-06-10T16:42:04","slug":"use-powershell-invoke-command-for-remoting","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-invoke-command-for-remoting\/","title":{"rendered":"Use PowerShell Invoke-Command for Remoting"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Windows PowerShell MVP, Don Jones, talks about using the Invoke-Command cmdlet for remoting.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, here. I am really excited about the idea I had for this week, and I hope you will be too. I asked Candace Gillhoolley at Manning Press about posting some sample works from some of the Manning Press library of books. She responded enthusiastically and shared five samples that we will post this week. Today we present Don Jones\u2019 <em>Learn Windows PowerShell in a Month of Lunches<\/em>.<\/p>\n<h2><strong><a target=\"_blank\" href=\"http:\/\/www.manning.com\/jones\/\" rel=\"noopener\">Learn Windows PowerShell in a Month of Lunches<\/a>****\u00a0<\/strong><\/h2>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3583.HSG-6-13-11-1_32FF8250.jpg\"><img decoding=\"async\" height=\"193\" width=\"149\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4760.HSG-6-13-11-1_thumb_52AE5C18.jpg\" alt=\"HSG-6-13-11-1\" border=\"0\" title=\"HSG-6-13-11-1\" style=\"padding-left: 0px;padding-right: 0px;padding-top: 0px;border: 0px\" \/><\/a><\/p>\n<p>By Don Jones<\/p>\n<p>One of the coolest things in Windows PowerShell is to send a command to multiple remote computers at the same time. In this article, based on chapter 10 of <a target=\"_blank\" href=\"http:\/\/www.manning.com\/jones\/\" rel=\"noopener\"><i>Learn Windows PowerShell in a Month of Lunches<\/i><\/a>, author Don Jones explains how to use the <strong>Invoke-Command<\/strong> cmdlet to execute one-to-many, or 1:n, remoting. To save 35% on your next purchase, use Promotional Code <strong>jones1035<\/strong> when you check out at <a target=\"_blank\" href=\"https:\/\/www.manning.com\" rel=\"noopener\">www.manning.com<\/a>.<\/p>\n<p><strong><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5417.manning_534AC468.png\"><img decoding=\"async\" height=\"26\" width=\"154\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8535.manning_thumb_7A18DAA8.png\" alt=\"manning\" border=\"0\" title=\"manning\" style=\"padding-left: 0px;padding-right: 0px;padding-top: 0px;border-width: 0px\" \/><\/a><\/strong><\/p>\n<h2><strong>Using Invoke-Command for Remoting<\/strong><\/h2>\n<p>The trick I will show you in this article\u2014and one of the coolest things in Windows PowerShell\u2014is to send a command to *multiple remote computers at the same time. *That\u2019s right, full-scale distributed computing. Each computer will independently execute the command and send the results right back to you. It\u2019s all done with:<\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">Invoke-Command -computername Server-R2,Server-DC4,Server12 `<br \/>\u00a0-command { Get-EventLog Security -newest 200 |<\/span><\/span><\/span>\n> <\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">\u00a0Where { $_.EventID -eq 1212 }}<\/span><\/span><\/span><span>\u00a0<\/span>\n> <\/p>\n<p><strong>Try it now<\/strong><\/p>\n<p>Go ahead and run this command. Substitute the name of your remote computer (or computers) where I\u2019ve put my three computer names.<\/p>\n<p>Everything in those outermost {braces} will get transmitted to the remote computers\u2014all three of them. By default, PowerShell will talk to up to 32 computers at once; if you specified more than that, it will queue them up, so that, as one computer completes, the next one in line will begin. If you have a really awesome network and powerful computers, you could raise that number by specifying the <strong>-throttleLimit<\/strong> parameter of <strong>Invoke-Command<\/strong>\u2014read the command\u2019s help for more information.<\/p>\n<h3><strong>Be careful about the punctuation<\/strong><\/h3>\n<p>We need to pause for a moment and really dig into that example command because this is a case where Windows PowerShell\u2019s punctuation can get confusing, and that confusion can make you do the wrong thing when you start constructing these command lines on your own. There are two commands in that example which use curly braces: <strong>Invoke-Command<\/strong> and Where (which is an alias for <strong>Where-Object<\/strong>). Where is entirely nested within the outer set of braces. The outermost set of braces enclose everything that is being sent to the remote computers for execution; that includes:<\/p>\n<blockquote>\n<p><span class=\"CodeinText\" style=\"line-height: normal;list-style-type: disc\"><span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">Get-EventLog Security -newest 200 | Where { $_.EventID -eq 1212 }<\/span><\/span><\/span><\/span><\/p>\n<\/blockquote>\n<p>I should tell you that you won\u2019t see the <strong>-command<\/strong> parameter in the Help for <strong>Invoke-Command<\/strong>\u2014yet, the command I just showed you will work fine. The <strong>-command<\/strong> parameter is actually an <em>alias, *or nickname, for the <strong>-scriptblock<\/strong> parameter that you *will<\/em> see listed in the Help. I just have an easier time remembering <strong>-command<\/strong>, so I tend to use it instead of <strong>-scriptblock<\/strong>\u2014but they both work the same way.<\/p>\n<p>If you read the help for <strong>Invoke-Command<\/strong> carefully (see how I\u2019m continuing to push those help files?), then you\u2019ll also notice a parameter that lets you specify a script file, rather than a command. That parameter lets you send an entire script to the remote computers\u2014meaning, you can automate some pretty complex tasks and have each computer do its own share of the work.<\/p>\n<p><strong>Try it now<\/strong><\/p>\n<p>Make sure you can identify the <strong>-scriptblock<\/strong> parameter in the help for Invoke-Command and that you can spot the parameter that would enable you to specify the file path and name instead of a scriptblock.<\/p>\n<p>I want to circle back to the <strong>-computername<\/strong> parameter for just a bit. When I first used <strong>Invoke-Command<\/strong>, I typed a comma-separated list of computer names, just as I did in the example above. But I have a <em>lot<\/em> of computers I work with, so I didn\u2019t want to have to type them all in every time. I actually keep text files for some of my common computer categories, like Web servers and domain controllers. Each text file contains one computer name per line, and that\u2019s it\u2014no commas, no quotes, no nothing. Windows PowerShell makes it really easy for me to use those files:<\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">Invoke-Command -command { dir } `<br \/>\u00a0-computerName (Get-Content webservers.txt)<\/span><\/span><\/span>\n> <\/p>\n<p>The parentheses there force Windows PowerShell to execute <strong>Get-Content<\/strong> first\u2014pretty much the same way parentheses work in math. The results of <strong>Get-Content<\/strong> are then stuck into the <strong>-computerName<\/strong> parameter, which then works against each of the computers that were listed in the file.<\/p>\n<p>I also sometimes want to query computer names from Active Directory. This is a bit trickier. I can use the <strong>Get-ADComputer<\/strong> command (from the ActiveDirectory module in Windows Server 2008 R2) to retrieve computers, but I can\u2019t just stick that command in parentheses like I did with <strong>Get-Content<\/strong>. Why not? Because <strong>Get-Content<\/strong> is just producing simple strings of text, which <strong>-computername<\/strong> is expecting. <strong>Get-ADComputer<\/strong>, on the other hand, is producing entire computer objects, and the <strong>-computername<\/strong> parameter won\u2019t know what to do with them. So if I want to use <strong>Get-ADComputer<\/strong>, I need to find a way to <em>just<\/em> get the <em>values<\/em> from those computer objects\u2019 Name properties. Here\u2019s how:<\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">Invoke-Command -command { dir } -computerName (<\/span><\/span><\/span>\n> <\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">\u00a0Get-ADComputer -filter * -searchBase &#8220;ou=Sales,dc=company,dc=pri&#8221; |<\/span><\/span><\/span>\n> <\/p>\n<blockquote>\n<\/blockquote>\n<p class=\"Code\" style=\"line-height: normal;list-style-type: disc;margin: 0in 0in 0pt\">\n>   <span><span style=\"font-family: Lucida Sans Typewriter\"><span style=\"color: #000000\">\u00a0Select-Object -expand Name )<\/span><\/span><\/span>\n> <\/p>\n<p><strong>Try it now<\/strong><\/p>\n<p>If you\u2019re running Windows PowerShell on a Windows Server 2008 R2 domain controller or on a Windows 7 computer that has the Remote Server Administration Toolkit installed, then you can run <strong>Import-Module<\/strong> <strong>ActiveDirectory<\/strong> and then try the above command. If your test domain doesn\u2019t have a Sales OU that contains a computer account, then change ou=Sales to ou=Domain Controllers and be sure to change company and pri to the appropriate values for your domain. (For example, if your domain is mycompany.org, you would substitute mycompany for company and org for pri.)<\/p>\n<p>Within the parentheses, I\u2019ve piped the computer objects to <strong>Select-Object<\/strong>, and I\u2019ve used their -expand parameter. I\u2019m telling it to expand the <strong>Name<\/strong> property of whatever came in\u2014in this case, those computer objects. So, the result of that entire parenthetical expression will be a bunch of computer names, not computer objects\u2014and computer names are exactly what the <strong>-computername<\/strong> parameter wants to see.<\/p>\n<p>By the way, just to be complete, I should mention that the -filter parameter of <strong>Get-ADComputer<\/strong> specifies that all computers should be included in the command\u2019s output. The <strong>-searchBase<\/strong> parameter tells the command to start looking for computers in the specified location\u2014in this case, the Sales OU of the company.pri domain. The <strong>Get-ADComputer<\/strong> command is only available on Windows Server 2008 R2 and on Windows 7 after installing the Remote Administration Server Toolkit (RSAT). On those operating systems, you have to run <strong>Import-Module ActiveDirectory<\/strong> to actually load the Active Directory cmdlets into the shell so that they can be used.<\/p>\n<h3><strong>Ideas for on your own<\/strong><\/h3>\n<p>One of the Windows PowerShell modules included in Windows 7 is Troubleshooting Pack, which provides command-line access to the new troubleshooting pack functionality in the operating system. I always tell my students and clients to consider enabling Windows PowerShell remoting on all of their client computers, in part because it gives you remote command-line access to those troubleshooting packs. When a user calls for help, rather than walking them through a wizard over the phone, you can just remote in and run the same wizard, in command-line form rather than GUI form, yourself.<\/p>\n<p>Guest Writer\u2019s Week will continue tomorrow when we will have a post from Richard Siddaway.<\/p>\n<p>I invite you to follow me on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\" rel=\"noopener\">Twitter<\/a> and <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguysfacebook\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"&#109;&#97;&#x69;&#x6c;&#116;&#111;&#x3a;&#x73;c&#114;&#105;&#x70;&#x74;&#101;&#114;&#x40;&#x6d;&#105;&#99;&#x72;&#x6f;s&#111;&#102;&#x74;&#x2e;&#99;&#111;&#x6d;\">&#x73;c&#114;&#105;&#x70;&#x74;&#101;&#114;&#x40;&#x6d;&#105;&#99;&#x72;&#x6f;s&#111;&#102;&#x74;&#x2e;&#99;&#111;&#x6d;<\/a>, or post your questions on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Windows PowerShell MVP, Don Jones, talks about using the Invoke-Command cmdlet for remoting. Microsoft Scripting Guy, Ed Wilson, here. I am really excited about the idea I had for this week, and I hope you will be too. I asked Candace Gillhoolley at Manning Press about posting some sample works from some of [&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":[64,51,56,57,3,4,45],"class_list":["post-13641","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-don-jones","tag-getting-started","tag-guest-blogger","tag-remoting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Windows PowerShell MVP, Don Jones, talks about using the Invoke-Command cmdlet for remoting. Microsoft Scripting Guy, Ed Wilson, here. I am really excited about the idea I had for this week, and I hope you will be too. I asked Candace Gillhoolley at Manning Press about posting some sample works from some of [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13641","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=13641"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13641\/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=13641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=13641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=13641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}