{"id":2999,"date":"2013-08-21T00:01:00","date_gmt":"2013-08-21T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/08\/21\/powershell-workflow-for-mere-mortals-part-3\/"},"modified":"2013-08-21T00:01:00","modified_gmt":"2013-08-21T00:01:00","slug":"powershell-workflow-for-mere-mortals-part-3","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-workflow-for-mere-mortals-part-3\/","title":{"rendered":"PowerShell Workflow for Mere Mortals: Part 3"},"content":{"rendered":"<p><strong>Summary<\/strong>: Microsoft Scripting Guy Ed Wilson continues his five-part series about Windows PowerShell Workflow.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\" \/>&nbsp;Hey, Scripting Guy! So what&rsquo;s up with Windows PowerShell workflows and activities? I do not know what an activity is. Can you help me?<\/p>\n<p>&mdash;CJ<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\" \/>&nbsp;Hello CJ,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Ah&hellip;this afternoon, I am sipping a cup of Darjeeling Earl Grey tea with a bit of cinnamon stick, and I added just a bit of lavender honey from a nearby lavender farm. I am accompanying my tea with a 90% cocoa bar with black currants and hazelnuts. The combination is absolutely stunning.<\/p>\n<p><strong>Note<\/strong> &nbsp;This is the third in a five-part series of blog posts about Windows PowerShell Workflow for &ldquo;mere mortals.&rdquo; Before you read this post, please read:&nbsp;<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/08\/19\/powershell-workflow-for-mere-mortals-part-1.aspx\" target=\"_blank\">PowerShell Workflow for Mere Mortals: Part 1<\/a><\/li>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/08\/20\/powershell-workflow-for-mere-mortals-part-2.aspx\" target=\"_blank\">PowerShell Workflow for Mere Mortals: Part 2<\/a><\/li>\n<\/ul>\n<p>For more information about workflow, see these Hey, Scripting Guy! Blog posts:&nbsp;<a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/workflow\/\" target=\"_blank\">Windows PowerShell Workflow<\/a>.&nbsp;<\/p>\n<h2>Workflow activities<\/h2>\n<p>A Windows PowerShell Workflow is made up of a series of activities. In fact, the basic unit of work in a Windows PowerShell Workflow is called an activity. There are five types of Windows PowerShell Workflow activities that are available for use. The following table describes the types of activities.<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p><strong>Activity<\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p><strong>Description<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p>CheckPoint-Workflow (alias = PSPersist)<\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p>Takes a checkpoint. Saves the state and data of a workflow in progress. If the workflow is interrupted or rerun, it can restart from any checkpoint.<\/p>\n<p>Use the <strong>Checkpoint-Workflow<\/strong> activity along with the <strong>PSPersist<\/strong> workflow common parameter and the <strong>PSPersistPreference<\/strong> variable to make your workflow robust and recoverable.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p>&nbsp;<\/p>\n<p>ForEach -Parallel<\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p>Runs the statements in the script block once for each item in a collection. The items are processed in parallel. The statements in the script block run sequentially.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p>Parallel<\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p>Allows all statements in the script block to run at the same time. The order of execution is undefined.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p>Sequence<\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p>Creates a block of sequential statements within a parallel script block. The <strong>Sequence<\/strong> script block runs in parallel with other activities in the <strong>Parallel<\/strong> script block. However, the statements in the <strong>Sequence<\/strong> script block run in the order in which they appear. <strong>Sequence<\/strong> is valid only within a <strong>Parallel<\/strong> script block.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"271\">\n<p>Suspend-Workflow<\/p>\n<\/td>\n<td valign=\"top\" width=\"367\">\n<p>Stops a workflow temporarily. To resume the workflow, use the <strong>Resume-Job <\/strong>cmdlet.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>&nbsp;Windows PowerShell cmdlets as activities<\/h2>\n<p>Windows PowerShell cmdlets from the core modules are automatically implemented as activities for use in a Windows PowerShell Workflow. These core modules, all begin with the name Microsoft.PowerShell. To find these cmdlets, I can use the <strong>Get-Command<\/strong> cmdlet as shown here:<\/p>\n<p style=\"padding-left: 30px\">Get-Command -Module microsoft.powershell*<\/p>\n<p>The command and the associated output from the command are shown in the image that follows.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4834.HSG-8-21-13-01.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4834.HSG-8-21-13-01.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<h2>Disallowed core cmdlets<\/h2>\n<p>However, not all of the cmdlets from the Windows PowerShell core modules are permitted as automatic activities for Windows PowerShell Workflows. The reason for this is that some of the core cmdlets do not work well in workflows. A quick look at the disallowed list makes this abundantly clear. The following table lists the disallowed core cmdlets.<\/p>\n<p>&nbsp;<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\">\n<p>Add-History<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Invoke-History<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Add-PSSnapin<\/p>\n<\/td>\n<td valign=\"top\">\n<p>New-Alias<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Clear-History<\/p>\n<\/td>\n<td valign=\"top\">\n<p>New-Variable<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Clear-Variable<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Out-GridView<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Complete-Transaction<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Remove-PSBreakpoint<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Debug-Process<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Remove-PSSnapin<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Disable-PSBreakpoint<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Remove-Variable<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Enable-PSBreakpoint<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-Alias<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Enter-PSSession<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-PSBreakpoint<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Exit-PSSession<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-PSDebug<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Export-Alias<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-StrictMode<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Export-Console<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-TraceMode<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-Alias<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Set-Variable<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-History<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Start-Transaction<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-PSBreakpoint<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Start-Transcript<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-PSCallStack<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Stop-Transcript<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-PSSnapin<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Trace-Command<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-Transaction<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Undo-Transaction<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Get-Variable<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Use-Transaction<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\">\n<p>Import-Alias<\/p>\n<\/td>\n<td valign=\"top\">\n<p>Write-Host&nbsp;<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Non-Automatic cmdlet activities<\/h2>\n<p>If a cmdlet is not in the Windows PowerShell core modules, it does not mean that it is excluded. In fact, it probably is not excluded. Therefore, when a non-core Windows PowerShell cmdlet is used in a Windows PowerShell Workflow, Windows PowerShell will automatically run the cmdlet as an InlineScript activity.<\/p>\n<p>An InlineScript activity permits me to run commands in a Windows PowerShell workflow, and to share data that would not be otherwise permitted.<\/p>\n<p>In the <strong>InlineScript<\/strong> script block, I can call all Windows PowerShell commands and expressions and share state and data within the session. This includes imported modules and variable values. For example, the cmdlets listed in the previous table that are not permitted in a Windows PowerShell workflow, could be included in an <strong>InlineScript<\/strong> activity.<\/p>\n<h2>Parallel activities<\/h2>\n<p>To create a Windows PowerShell Workflow that uses a parallel workflow activity, I use the <strong>Parallel<\/strong> keyword, and I supply a script block. The following workflow illustrates this technique:<\/p>\n<p style=\"padding-left: 30px\">WorkFlow Get-EventLogData<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;Parallel<\/p>\n<p style=\"padding-left: 30px\">&nbsp;{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-EventLog -LogName application -Newest 1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-EventLog -LogName system -Newest 1<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; Get-EventLog -LogName &#8216;Windows PowerShell&#8217; -Newest 1 } }<\/p>\n<p>When I run the script that contains the <strong>Get-EventLogData<\/strong> workflow, I go to the execution pane of the Windows PowerShell ISE to execute the workflow. What happens is that the three <strong>Get-EventLog<\/strong> cmdlet commands execute in parallel. This results in a powerful and quick way to grab event log data. If I call the workflow with no parameters, it runs on my local computer. This is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7711.HSG-8-21-13-02.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7711.HSG-8-21-13-02.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>The cool thing is that with a Windows PowerShell Workflow, I automatically gain access to several automatic parameters. One of the automatic parameters is <strong>PSComputerName<\/strong>. Therefore, with no additional work (this workflow does not exist on Server 1 or Server2&mdash;it only exists on my workstation), I can use the automatic <strong>PSComputerName<\/strong> workflow parameter, and run the workflow on two remote servers. This is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7331.HSG-8-21-13-03.png\"><img decoding=\"async\" title=\"Image of command output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7331.HSG-8-21-13-03.png\" alt=\"Image of command output\" \/><\/a><\/p>\n<p>Because I am not accessing the <strong>PSComputerName<\/strong> automatic parameter directly within my Windows PowerShell activity, I am actually using an automatic workflow parameter. For more information, see the following online Help: <a href=\"http:\/\/technet.microsoft.com\/library\/jj129719.aspx\" target=\"_blank\">about_WorkflowCommonParameters<\/a>.<\/p>\n<p>There are also workflow activity-specific common parameters. For more information, see <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/jj574194.aspx\" target=\"_blank\">Using Activities in Script Workflows<\/a>.<\/p>\n<p>CJ, that is all there is to using Windows PowerShell Workflow activities. Windows PowerShell Workflow Week will continue tomorrow when I will talk about more Windows PowerShell Workflow activities.<\/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><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy Ed Wilson continues his five-part series about Windows PowerShell Workflow. &nbsp;Hey, Scripting Guy! So what&rsquo;s up with Windows PowerShell workflows and activities? I do not know what an activity is. Can you help me? &mdash;CJ &nbsp;Hello CJ, Microsoft Scripting Guy, Ed Wilson, is here. Ah&hellip;this afternoon, I am sipping a cup [&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-2999","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 continues his five-part series about Windows PowerShell Workflow. &nbsp;Hey, Scripting Guy! So what&rsquo;s up with Windows PowerShell workflows and activities? I do not know what an activity is. Can you help me? &mdash;CJ &nbsp;Hello CJ, Microsoft Scripting Guy, Ed Wilson, is here. Ah&hellip;this afternoon, I am sipping a cup [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2999","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=2999"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2999\/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=2999"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2999"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2999"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}