{"id":2241,"date":"2012-07-21T13:06:00","date_gmt":"2012-07-21T13:06:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2012\/07\/21\/new-workflow-makeiteasy-authoring-workflows-using-powershell-extended-syntax\/"},"modified":"2024-02-26T11:59:43","modified_gmt":"2024-02-26T19:59:43","slug":"new-workflow-makeiteasy-authoring-workflows-using-powershell-extended-syntax","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/new-workflow-makeiteasy-authoring-workflows-using-powershell-extended-syntax\/","title":{"rendered":"New-Workflow \u2013MakeItEasy: Authoring Workflows using PowerShell Extended Syntax"},"content":{"rendered":"<p>Some time back, in his <a href=\"http:\/\/blogs.technet.com\/b\/windowsserver\/archive\/2012\/05\/30\/windows-server-2012-powershell-3-0-and-devops-part-2.aspx\">blog post<\/a>, Jeffrey Snover introduced one of the new Windows PowerShell 3.0 feature \u2013 <strong>Windows PowerShell Workflow<\/strong>. In that post, you saw a glimpse of how to author workflows using PowerShell syntax. This post dives into more details of authoring workflows using PowerShell syntax and various extensions to it.<\/p>\n<h2>Why we chose to extend the PowerShell Language for Workflow Authoring<\/h2>\n<p>As Jeffrey mentioned in that blog post, Windows Workflow Foundation traditionally has been a developer-focused feature that requires Visual Studio and a lot of code to create a solution. To review the solution, another person has to understand XAML or they have to install Workflow Designer. Authoring workflows by using Windows PowerShell is much easier and overcomes the development hurdles. Additionally, you get the benefit of sharing the workflows by simply pasting them into an email or publishing them online.<\/p>\n<p>Another reason, as pointed out in <a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2012\/03\/17\/when-windows-powershell-met-workflow.aspx\">another blog post<\/a>, is our promise to the PowerShell community about learning once and reusing that knowledge over and over again:<\/p>\n<blockquote><p><b><i>\u201c \u2026 We respect your investment in learning Windows PowerShell by reusing concepts over and over to make sure learning Windows PowerShell was the best thing you ever did. \u2026\u201d<\/i><\/b><b><i><\/i><\/b><\/p><\/blockquote>\n<p>While designing the workflow authoring experience, we kept this promise in mind. We also thought of ways to work with existing tools and, hence, came up with two approaches to workflow authoring:<\/p>\n<ol>\n<li><b>Script-based Workflow Authoring<\/b>: Leverage and extend the PowerShell language for workflows so IT Pros can reuse their existing PowerShell scripting skills.<\/li>\n<li><b>XAML-based Workflow Authoring:<\/b> Plug into the Visual Studio Workflow Designer experience so developers can easily get the management activities in their existing environment and continue leveraging their XAML and Visual Studio knowledge.<\/li>\n<\/ol>\n<p>This post will dive into details of the former approach for workflow authoring: PowerShell script-based workflows. In a later blog post, we will look into the XAML-based authoring experience.<\/p>\n<p>Although there are multiple ways to showcase the new script-based workflow experience, we will explain it by using a real-world example: <span style=\"text-decoration: underline;\">Creating virtual machines on a Hyper-V capable host machine and joining those virtual machines to a domain.<\/span> This example is a good workflow sample because it has all the necessary workflow characteristics \u2013 long running task across multiple machines that require robustness due to machine reboots.<\/p>\n<p>The benefit of this approach is that by the end of this blog, you will have a real-world workflow sample that can easily be used in your environment. <a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5661.wlEmoticon-smile_438CBD30.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20395\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5661.wlEmoticon-smile_438CBD30.png\" alt=\"Image 5661 wlEmoticon smile 438CBD30\" width=\"19\" height=\"19\" \/><\/a><\/p>\n<h2>Workflow Extensions to the PowerShell Language<\/h2>\n<p>In next couple of sections, we will look at various extensions to the PowerShell language that expose and enable Windows Workflow Foundation concepts.<\/p>\n<h3>Workflow Keyword<\/h3>\n<p>The most important of extensions to the PowerShell language is the <b>workflow<\/b> keyword. To create a workflow, use the <b>workflow<\/b> keyword, followed by a name for the workflow and, then, followed by the body of the workflow, such as:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8625.Invoke-HelloWorld_thumb_5128082C.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20378\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8625.Invoke-HelloWorld_thumb_5128082C.png\" alt=\"Image 8625 Invoke HelloWorld thumb 5128082C\" width=\"255\" height=\"51\" \/><\/a><\/p>\n<p>As you can see, if you know how to write a PowerShell function, you are 80% on the way to being able to write a workflow.<\/p>\n<p><i>Note: The behavior of a workflow is different than a function and it has a few more rules that we will delve into in another blog post soon.<\/i><\/p>\n<p>After knowing how easy it is to create a workflow, let\u2019s build our workflow for creating virtual machines (VM). We will name it <b>Install-VM<\/b> \u2013 using a verb-noun name just like those of any other PowerShell command. We will add parameters to our workflow that will specify virtual hard disk (VHD) location for VMs, default prefix for VM name and the number of VM to create.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0181.Install-VM-Param_thumb_1FBC480D.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20380\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0181.Install-VM-Param_thumb_1FBC480D.png\" alt=\"Image 0181 Install VM Param thumb 1FBC480D\" width=\"414\" height=\"176\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0181.Install-VM-Param_thumb_1FBC480D.png 414w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0181.Install-VM-Param_thumb_1FBC480D-300x128.png 300w\" sizes=\"(max-width: 414px) 100vw, 414px\" \/><\/a><\/p>\n<blockquote><p><i>Note: As you might notice, in Windows PowerShell Workflow, you can specify default values for the parameters, just like you do in functions.<\/i><\/p><\/blockquote>\n<p>In the example above, notice that Windows PowerShell ISE recognizes the workflow and its content and colorizes them appropriately, just like it does for any other PowerShell command.<\/p>\n<h3><a name=\"ParallelExecution\"><\/a>Parallel Execution<\/h3>\n<p>The underlying Windows Workflow Foundation runtime supports running activities or commands in parallel. We expose this capability in Windows PowerShell Workflow through the <b>parallel<\/b> keyword, as well as <b>foreach-paralle<\/b>l, an enhancement to the ForEach statement. With parallel execution, you can significantly reduce the operation time across a set of machines.<\/p>\n<p>Additionally, to execute a collection of activities or commands in order (not in parallel) within a <b>parallel <\/b>block, use the <b>sequence <\/b>block, such as:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4073.Invoke-ParallelWorkflow_thumb_0E810ABF.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20381\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4073.Invoke-ParallelWorkflow_thumb_0E810ABF.png\" alt=\"Image 4073 Invoke ParallelWorkflow thumb 0E810ABF\" width=\"432\" height=\"250\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4073.Invoke-ParallelWorkflow_thumb_0E810ABF.png 432w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4073.Invoke-ParallelWorkflow_thumb_0E810ABF-300x174.png 300w\" sizes=\"(max-width: 432px) 100vw, 432px\" \/><\/a><\/p>\n<p>Now let\u2019s go back to our <a href=\"#DefinitionAndParam\">previous Install-VM<\/a> workflow. We&#8217;ll use a <b>foreach \u2013parallel <\/b>block to add logic for creating VMs in parallel.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8814.Install-VM-ForeachParallel_thumb_195DC1D8.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20382\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8814.Install-VM-ForeachParallel_thumb_195DC1D8.png\" alt=\"Image 8814 Install VM ForeachParallel thumb 195DC1D8\" width=\"547\" height=\"310\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8814.Install-VM-ForeachParallel_thumb_195DC1D8.png 547w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8814.Install-VM-ForeachParallel_thumb_195DC1D8-300x170.png 300w\" sizes=\"(max-width: 547px) 100vw, 547px\" \/><\/a><\/p>\n<blockquote><p><i>Note: In order to call <b>New-VM<\/b> and <b>New-VHD<\/b> commands, you need to install Hyper-V module.<\/i><\/p><\/blockquote>\n<h3>Checkpoint Workflow Execution<\/h3>\n<p>Windows Workflow Foundation allows a workflow to persist or checkpoint all aspects of its state by using an explicit call to the <b>Persist<\/b> activity. The same feature is exposed through the <b>Checkpoint-Workflow<\/b> command in Windows PowerShell Workflow.. With the use of <b>Checkpoint-Workflow,<\/b> Window PowerShell Workflow checkpoints the workflow state and saves the workflow data to the persistence store. In case of unintended interruptions (machine reboot, process crash, network disruption, etc.), the workflow execution resumes from the last persistence point. Alternatively, to achieve similar results, you can add <b>-PSPersist $true<\/b> at the end of an activity or command.<\/p>\n<p>Now let\u2019s add a <b>Checkpoint-Workflow<\/b> call to our <a href=\"#CreateVM\">previous Install-VM<\/a> workflow to save the workflow state.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3301.Install-VM-Checkpoint_thumb_0E14D7CA.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20383\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3301.Install-VM-Checkpoint_thumb_0E14D7CA.png\" alt=\"Image 3301 Install VM Checkpoint thumb 0E14D7CA\" width=\"413\" height=\"160\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3301.Install-VM-Checkpoint_thumb_0E14D7CA.png 413w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3301.Install-VM-Checkpoint_thumb_0E14D7CA-300x116.png 300w\" sizes=\"(max-width: 413px) 100vw, 413px\" \/><\/a><\/p>\n<blockquote><p><i>Note: Just look at the <b>param<\/b> and <b>foreach \u2013parallel<\/b> block above and you will notice another cool ISE feature: <\/i><i>collapsible regions.<\/i><\/p><\/blockquote>\n<h3><a name=\"InlineScript\"><\/a>InlineScript: Running Isolated Blocks of Windows PowerShell Script<\/h3>\n<p>By default, each command in a workflow is executed with no PowerShell state sharing. Variables created by one command are not visible to the next command. But, by using the <b>inlineScript<\/b> keyword it is possible to execute a collection of PowerShell commands as a single execution unit<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8664.Invoke-InlineScript_thumb_74ACD48F.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20384\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8664.Invoke-InlineScript_thumb_74ACD48F.png\" alt=\"Image 8664 Invoke InlineScript thumb 74ACD48F\" width=\"310\" height=\"128\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8664.Invoke-InlineScript_thumb_74ACD48F.png 310w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8664.Invoke-InlineScript_thumb_74ACD48F-300x124.png 300w\" sizes=\"(max-width: 310px) 100vw, 310px\" \/><\/a><\/p>\n<blockquote><p><i>Note: As mentioned in section 5 of <\/i><a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2012\/06\/19\/high-level-architecture-of-windows-powershell-workflow-part-2.aspx\"><i>PowerShell Workflow architecture<\/i><\/a><i>, for reliability reasons, by default, <b>inlineScript<\/b> runs in a separate process<\/i><i><\/i><\/p><\/blockquote>\n<h3><a name=\"UsingWithVariables\"><\/a>Accessing Workflow Variables from Different Execution Scopes<\/h3>\n<p>Just like PowerShell remoting in PowerShell 3.0, Windows PowerShell Workflow supports the <b>$Using:&lt;variable name&gt; <\/b>scope modifier. This new scope modifier can access workflow variables into the context of an <a href=\"#InlineScript\">inlineScript<\/a>.<\/p>\n<p>Unlike PowerShell, Windows Workflow Foundation does not support dynamic scoping of variables. This means that a variable that is defined in the parent scope cannot be redefined in a child scope. In Windows PowerShell Workflow, to change a workflow-scoped variable from any inner scope, use the <b>$workflow:&lt;variable name&gt; <\/b>scope modifier.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3225.Invoke-WithUsingandWorkflowScope_thumb_7AF3AB1D.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20385\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3225.Invoke-WithUsingandWorkflowScope_thumb_7AF3AB1D.png\" alt=\"Image 3225 Invoke WithUsingandWorkflowScope thumb 7AF3AB1D\" width=\"600\" height=\"285\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3225.Invoke-WithUsingandWorkflowScope_thumb_7AF3AB1D.png 600w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3225.Invoke-WithUsingandWorkflowScope_thumb_7AF3AB1D-300x143.png 300w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>Now, we will use our new <a href=\"#ParallelExecution\">foreach -parallel<\/a>, <a href=\"#InlineScript\">inlineScript<\/a> and <a href=\"#UsingWithVariables\">$using<\/a> concepts, to update our <a href=\"#SaveWorkflowState\">previous Install-VM<\/a><b> <\/b>workflow by adding logic for starting the VMs and getting their IP addresses in parallel.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20386\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E.png\" alt=\"Image 1425 Install VM VMIPAddress thumb 12E17A0E\" width=\"579\" height=\"565\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E.png 579w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E-300x293.png 300w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E-24x24.png 24w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1425.Install-VM-VMIPAddress_thumb_12E17A0E-48x48.png 48w\" sizes=\"(max-width: 579px) 100vw, 579px\" \/><\/a><\/p>\n<blockquote><p><i>Note: All the commands in workflow have a <b>\u2013DisplayName<\/b> common parameter to provide a custom or friendly name for the command. In the previous example, we used it on <b>inlineScript<\/b>.<\/i><\/p><\/blockquote>\n<h3>Suspending a Workflow from within the workflow<\/h3>\n<p>Windows PowerShell Workflow has a <b>Suspend-Workflow<\/b> command that suspends the workflow during its execution. This command gives the workflow author complete control over the workflow suspension behavior independent of the workflow user. For example, a workflow can detect a problem that requires manual intervention, notify the operator of this condition, and then suspend operations until the operator corrects the situation and resumes the workflow.<\/p>\n<p>Let us update our <a href=\"#StartVMandWaitForIP\">previous Install-VM<\/a><b> <\/b>workflow to send an email to a senior admin and suspend itself. Once the senior admin gets the email, he\/she can resume the workflow manually.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8053.Install-VM-Suspend_thumb_641BC16B.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20387\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8053.Install-VM-Suspend_thumb_641BC16B.png\" alt=\"Image 8053 Install VM Suspend thumb 641BC16B\" width=\"660\" height=\"410\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8053.Install-VM-Suspend_thumb_641BC16B.png 660w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/8053.Install-VM-Suspend_thumb_641BC16B-300x186.png 300w\" sizes=\"(max-width: 660px) 100vw, 660px\" \/><\/a><\/p>\n<p>Additionally, you can integrate the workflow execution with the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/hh880865(v=vs.85).aspx\">Management Odata IIS Extension feature<\/a> of Windows Server 2012 to manage workflows from any Windows or non-Windows device that can understand HTTP requests. The PowerShell team demonstrated this feature at TechEd North America and TechEd Europe 2012. You can see a recording of this session <a href=\"https:\/\/channel9.msdn.com\/Events\/TechEd\/NorthAmerica\/2012\/WSV414\">here<\/a> (look at the 1:03:17 mark).<\/p>\n<h3>Workflow Calling Workflow<\/h3>\n<p>This feature of Windows PowerShell Workflow enables you to re-use workflows to create higher-level workflows, while leveraging your existing workflow investment, workflows from other users, and workflows from the PowerShell Community. To use this feature, the child workflow (e.g. <b>Join-Domain<\/b>) must be defined and imported into the PowerShell session in which the parent workflow is defined..<\/p>\n<p>Let\u2019s define a <b>Join-Domain<\/b> workflow that joins a machine to a domain. To complete the scenario, we will call <b>Join-Domain<\/b> from our <b>Install-VM <\/b>workflow.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/6102.Join-Domain_thumb_6378F6EC.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20388\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/6102.Join-Domain_thumb_6378F6EC.png\" alt=\"Image 6102 Join Domain thumb 6378F6EC\" width=\"673\" height=\"230\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/6102.Join-Domain_thumb_6378F6EC.png 673w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/6102.Join-Domain_thumb_6378F6EC-300x103.png 300w\" sizes=\"(max-width: 673px) 100vw, 673px\" \/><\/a><\/p>\n<p>Updated <b>Install-VM <\/b>workflow looks like as follows (and script is attached at the end of the blog post):<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1184.Install-VM-WithJoin-Domain_thumb_45404DB8.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20389\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1184.Install-VM-WithJoin-Domain_thumb_45404DB8.png\" alt=\"Image 1184 Install VM WithJoin Domain thumb 45404DB8\" width=\"692\" height=\"660\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1184.Install-VM-WithJoin-Domain_thumb_45404DB8.png 692w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1184.Install-VM-WithJoin-Domain_thumb_45404DB8-300x286.png 300w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/1184.Install-VM-WithJoin-Domain_thumb_45404DB8-24x24.png 24w\" sizes=\"(max-width: 692px) 100vw, 692px\" \/><\/a><\/p>\n<blockquote><p><i>NOTE: Notice that the param block of <b>Install-VM<\/b> has two additional parameters: $domainCred and $localCred. The <b>Join-Domain<\/b> workflow needs these values. <\/i><\/p><\/blockquote>\n<p>Additionally, you can define nested functions or nested workflows inside the workflows as well, such as:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4152.Invoke-NestedCommand_thumb_4FB5FBE0.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20390\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4152.Invoke-NestedCommand_thumb_4FB5FBE0.png\" alt=\"Image 4152 Invoke NestedCommand thumb 4FB5FBE0\" width=\"393\" height=\"270\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4152.Invoke-NestedCommand_thumb_4FB5FBE0.png 393w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/4152.Invoke-NestedCommand_thumb_4FB5FBE0-300x206.png 300w\" sizes=\"(max-width: 393px) 100vw, 393px\" \/><\/a><\/p>\n<h3>Finding and Running Your Workflow<\/h3>\n<p>As explained by Mir Rosenberg in an <a href=\"http:\/\/blogs.msdn.com\/b\/powershell\/archive\/2012\/03\/17\/when-windows-powershell-met-workflow.aspx\">earlier blog post<\/a>, Windows PowerShell Workflows behave just like other Windows PowerShell commands. You can discover them by using <b>Get-Command:<\/b><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5314.Get-Command_thumb_410B4FFB.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20391\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5314.Get-Command_thumb_410B4FFB.png\" alt=\"Image 5314 Get Command thumb 410B4FFB\" width=\"585\" height=\"190\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5314.Get-Command_thumb_410B4FFB.png 585w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/5314.Get-Command_thumb_410B4FFB-300x97.png 300w\" sizes=\"(max-width: 585px) 100vw, 585px\" \/><\/a><\/p>\n<p>You can run them interactively or use the <b>AsJob <\/b>common parameter of workflows to run any workflow as a background job.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3312.Invoke-Install-VM_thumb_3EF14F2C.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20392\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3312.Invoke-Install-VM_thumb_3EF14F2C.png\" alt=\"Image 3312 Invoke Install VM thumb 3EF14F2C\" width=\"591\" height=\"32\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3312.Invoke-Install-VM_thumb_3EF14F2C.png 591w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/3312.Invoke-Install-VM_thumb_3EF14F2C-300x16.png 300w\" sizes=\"(max-width: 591px) 100vw, 591px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0172.InvokeAsJob-Install-VM_thumb_3E851C37.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-20393\" src=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0172.InvokeAsJob-Install-VM_thumb_3E851C37.png\" alt=\"Image 0172 InvokeAsJob Install VM thumb 3E851C37\" width=\"706\" height=\"42\" srcset=\"https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0172.InvokeAsJob-Install-VM_thumb_3E851C37.png 706w, https:\/\/devblogs.microsoft.com\/powershell\/wp-content\/uploads\/sites\/30\/2012\/07\/0172.InvokeAsJob-Install-VM_thumb_3E851C37-300x18.png 300w\" sizes=\"(max-width: 706px) 100vw, 706px\" \/><\/a><\/p>\n<h3>Join-In<\/h3>\n<p>Now that you know how easy it is to author workflows using PowerShell syntax, please try your hand at creating couple of workflows for long-running multi-machine scenarios and tell us about your experience (and feature requests J ). As always, you can send feedback directly to us by using the <a href=\"http:\/\/connect.microsoft.com\/powershell\">Windows PowerShell Connect site<\/a>.<\/p>\n<p>While we create our next set of blog posts about Windows PowerShell Workflow, enjoy some additional resources about Windows PowerShell 3.0 and Windows PowerShell Workflow:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.windowsitpro.com\/blog\/powershell-with-a-purpose-blog-36\/windows-powershell\/powershell-v3-workflow-flagship-feature-140712\">PowerShell v3: Workflow is the Flagship Feature<\/a> (by Don Jones \u2013 PowerShell MVP)<\/li>\n<li><a href=\"http:\/\/halr9000.com\/article\/947\">PowerShell Workflow, Defined<\/a> (by Hal Rottenberg \u2013 PowerShell MVP)<\/li>\n<li><a href=\"http:\/\/technet.microsoft.com\/library\/hh847767.aspx\">PowerShell Workflow module<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/desktop\/microsoft.powershell.workflow(v=VS.85).aspx\">PowerShell Workflow SDK documentation<\/a><\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/hh852738(v=vs.85).aspx\">Authoring a Workflow using PowerShell Activities<\/a><\/li>\n<\/ul>\n<p>Hemant Mahawar [MSFT]\nSenior Program Manager\nWindows PowerShell<\/p>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/10\/33\/22\/71\/Install-VM.psm1\">Install-VM.psm1<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some time back, in his blog post, Jeffrey Snover introduced one of the new Windows PowerShell 3.0 feature \u2013 Windows PowerShell Workflow. In that post, you saw a glimpse of how to author workflows using PowerShell syntax. This post dives into more details of authoring workflows using PowerShell syntax and various extensions to it. Why [&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":[12,51,168,184,33,248,250,272,352,359],"class_list":["post-2241","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-cmdlet","tag-functions","tag-get-command","tag-getting-started","tag-language","tag-powershell","tag-powershell-3-0","tag-powershell-workflow","tag-windows-server-2012","tag-workflow"],"acf":[],"blog_post_summary":"<p>Some time back, in his blog post, Jeffrey Snover introduced one of the new Windows PowerShell 3.0 feature \u2013 Windows PowerShell Workflow. In that post, you saw a glimpse of how to author workflows using PowerShell syntax. This post dives into more details of authoring workflows using PowerShell syntax and various extensions to it. Why [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2241","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=2241"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2241\/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=2241"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=2241"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=2241"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}