{"id":400,"date":"2014-11-05T00:01:00","date_gmt":"2014-11-05T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/11\/05\/remotely-run-a-powershell-workflow\/"},"modified":"2014-11-05T00:01:00","modified_gmt":"2014-11-05T00:01:00","slug":"remotely-run-a-powershell-workflow","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/remotely-run-a-powershell-workflow\/","title":{"rendered":"Remotely Run a PowerShell Workflow"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft Scripting Guy, Ed Wilson, talks about running a Windows PowerShell workflow on a remote computer.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This morning it is beautiful outside. I am sitting on the porch sipping a cup of English Breakfast tea. I made a pot this morning, and I added some orange peel, Meyer lemon, and a bit of hibiscus flower to give it a nice tangy flavor.<\/p>\n<p>The Scripting Wife is still at the MVP Summit in Seattle, so I had to head to a local bakery to score some scones for breakfast. I found some really nice cinnamon scones, but they also had cinnamon sugar drizzled over the top&mdash;so I had to scratch that junk off. But after I had groomed the scone, it went well with the tea.<\/p>\n<p>Speaking of grooming stuff&hellip;<\/p>\n<p>One of the cool things about running a Windows PowerShell workflow through a remote server is that I can access modules that may not be available to my client machine. I can also employ alternate credentials.<\/p>\n<p>In my example today, there are actually four computers. The client machine is C1 and it is the computer from where I run the workflow. I target the domain controller, DC1, to be my workflow server. I do this by creating a PS Workflow Session on the target machine. This is really easy. Because I want to specify alternate credentials when I create the workflow session, I use the <b>&ndash;Credential<\/b> parameter in my command. I store the resultant session in a variable that I call <b>$wfs<\/b>. Here is the line of script:<\/p>\n<p style=\"margin-left:30px\">$wfs = New-PSWorkflowSession -ComputerName DC1 -Credential Nwtraders\\administrator<\/p>\n<p>The domain controller, DC1, is the workflow server. It is the server that uses Windows PowerShell workflow to run commands on remote servers.<\/p>\n<p>I use the <b>Invoke-Command<\/b> cmdlet, and I specify the session I just created. In my script block, I import two modules. I created the first one yesterday (Workflow-Install-Uninstall.psm1 module). It resides on a server as a shared resource, and therefore, it is easily accessible. When I call <b>Import-Module<\/b>, I specify the full path to the module.<\/p>\n<p>The second module is <b>ActiveDirectory<\/b>, and I do not need to import because it will automatically load when I call <b>Get-ADComputer<\/b>. But because I am loading modules, I may as well load this one. Here is the script:<\/p>\n<p style=\"margin-left:30px\">Invoke-Command -Session $wfs -ScriptBlock {<\/p>\n<p style=\"margin-left:30px\">&nbsp; Import-Module \\\\dc1\\Share\\PoshModules\\Workflow-Install-Uninstall-ISE.psm1 -verbose<\/p>\n<p style=\"margin-left:30px\">&nbsp; Import-module ActiveDirectory}<\/p>\n<p>The two target servers are S1 and S2, but I do not specify the computer names directly. Instead, I find the computer names by using the <b>Get-ADComputer<\/b> cmdlet from the <b>ActiveDirectory<\/b> module. It is more efficient to obtain computer names from Active Directory, because the list is always up-to-date, and it avoids a lot of typing.<\/p>\n<p>Because the servers begin with the letter &ldquo;S&rdquo; and are followed by a number, I use a regular expression for a pattern filter. I do this by piping all returned computer objects to the <b>Where-Object<\/b> command, and as shown here, I store the resultant matches in the <b>$cn<\/b> variable:<\/p>\n<p style=\"margin-left:30px\">$cn = Get-ADComputer -Filter * |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Where Name -match &#039;S[0-9]&#039;<\/p>\n<p>The last thing I need to do is to call the specific workflow from the module I loaded earlier. That script is shown here:<\/p>\n<p style=\"margin-left:30px\">Invoke-Command -Session $wfs {UnInstall-ISE -pscomputername $using:cn.name -AsJob}<\/p>\n<p>For the computer names, I need to select the <b>Name<\/b><i> <\/i>property from the computer objects I stored in the <b>$cn<\/b> variable. The <b>&ndash;pscomputername<\/b> parameter is an automatic parameter that appears in workflow commands.<\/p>\n<p>Because I retrieve the computer names from the DC1 computer, they are local objects. To bring the local objects into the work flow, I need to use the <b>$using<\/b> directive. The <b>&ndash;AsJob<\/b> parameter means that I will create a Windows PowerShell job, and therefore, I can manage the process with the <b>Job<\/b> cmdlets.<\/p>\n<p>Here is the basic drawing for my example today:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-11-5-14-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-11-5-14-1.png\" border=\"0\" alt=\" \" \/><\/a><\/p>\n<p>Here is he complete script for today&rsquo;s example:<\/p>\n<p style=\"margin-left:30px\">$wfs = New-PSWorkflowSession -ComputerName DC1 -Credential Nwtraders\\administrator<\/p>\n<p style=\"margin-left:30px\">Invoke-Command -Session $wfs -ScriptBlock {<\/p>\n<p style=\"margin-left:30px\">&nbsp; Import-Module \\\\dc1\\Share\\PoshModules\\Workflow-Install-Uninstall-ISE.psm1 -verbose<\/p>\n<p style=\"margin-left:30px\">&nbsp; Import-module ActiveDirectory}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $cn = Get-ADComputer -Filter * |<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Where Name -match &#039;S[0-9]&#039;<\/p>\n<p style=\"margin-left:30px\">Invoke-Command -Session $wfs {UnInstall-ISE -pscomputername $using:cn.name -AsJob}<\/p>\n<p>That is all there is to using Windows PowerShell to remotely run a workflow. Workflow Week will continue tomorrow when I will talk about more cool stuff.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about running a Windows PowerShell workflow on a remote computer. Microsoft Scripting Guy, Ed Wilson, is here. This morning it is beautiful outside. I am sitting on the porch sipping a cup of English Breakfast tea. I made a pot this morning, and I added some orange peel, [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,45,382],"class_list":["post-400","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-workflow"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about running a Windows PowerShell workflow on a remote computer. Microsoft Scripting Guy, Ed Wilson, is here. This morning it is beautiful outside. I am sitting on the porch sipping a cup of English Breakfast tea. I made a pot this morning, and I added some orange peel, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/400","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\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=400"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/400\/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=400"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=400"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=400"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}