了解適用於 Azure 自動化的 PowerShell 工作流程Learn PowerShell Workflow for Azure Automation

Azure 自動化中的 Runbook 會實作為 Windows PowerShell 工作流程,這是使用 Windows Workflow Foundation 的 Windows PowerShell 指令碼。Runbooks in Azure Automation are implemented as Windows PowerShell workflows, Windows PowerShell scripts that use Windows Workflow Foundation. 工作流程是一連串的程式化、連接步驟,執行長時間執行的工作,或是需要跨多個裝置或受控節點協調多個步驟。A workflow is a sequence of programmed, connected steps that perform long-running tasks or require the coordination of multiple steps across multiple devices or managed nodes.

雖然工作流程是使用 Windows PowerShell 語法編寫,並由 Windows PowerShell 啟動,但其是由 Windows Workflow Foundation 來處理。While a workflow is written with Windows PowerShell syntax and launched by Windows PowerShell, it is processed by Windows Workflow Foundation. 透過一般指令碼工作流程的好處包括同時對多個裝置執行動作,以及可從失敗自動復原。The benefits of a workflow over a normal script include simultaneous performance of an action against multiple devices and automatic recovery from failures.

注意

PowerShell 工作流程指令碼非常類似於 Windows PowerShell 指令碼,但有一些顯著的差異可能會對新使用者造成混淆。A PowerShell Workflow script is very similar to a Windows PowerShell script but has some significant differences that can be confusing to a new user. 因此,建議您只有在需要使用檢查點時,才使用 PowerShell 工作流程來撰寫 Runbook。Therefore, we recommend that you write your runbooks using PowerShell Workflow only if you need to use checkpoints.

如需這篇文章中的主題完整詳細資訊,請參閱開始使用 Windows PowerShell 工作流程For complete details of the topics in this article, see Getting Started with Windows PowerShell Workflow.

使用 Workflow 關鍵字Use Workflow keyword

將 PowerShell 指令碼轉換成 PowerShell 工作流程的第一個步驟,是使用 Workflow 關鍵字將其含括。The first step to converting a PowerShell script to a PowerShell workflow is enclosing it with the Workflow keyword. 一種工作流程,以 Workflow 關鍵字為開頭,後面接著括在大括弧中的指令碼主體。A workflow starts with the Workflow keyword followed by the body of the script enclosed in braces. 工作流程的名稱會遵循 Workflow 關鍵字,如下列語法所示:The name of the workflow follows the Workflow keyword as shown in the following syntax:

Workflow Test-Workflow
{
    <Commands>
}

工作流程的名稱必須符合自動化 Runbook 的名稱。The name of the workflow must match the name of the Automation runbook. 如果正在匯入 Runbook,則檔案名稱必須符合工作流程名稱,且必須以 .ps1 結尾。If the runbook is being imported, then the file name must match the workflow name and must end in .ps1.

若要將參數新增至工作流程,請使用 Param 關鍵字,如同您會對指令碼執行的動作。To add parameters to the workflow, use the Param keyword just as you would in a script.

了解 PowerShell 工作流程程式碼與 PowerShell 指令碼程式碼之間的差異Learn differences between PowerShell Workflow code and PowerShell script code

PowerShell 工作流程程式碼看起來幾乎類似於 PowerShell 指令碼,除了少數幾個重大變更。PowerShell Workflow code looks almost identical to PowerShell script code except for a few significant changes. 下列各節說明您必須對 PowerShell 指令碼進行的變更,以讓它在工作流程中執行。The following sections describe changes that you need to make to a PowerShell script for it to run in a workflow.

活動Activities

活動是工作流程中以序列執行的特定工作。An activity is a specific task in a workflow that is performed in a sequence. 執行工作流程時,Windows PowerShell 工作流程會自動將許多 Windows PowerShell Cmdlet 轉換為活動。Windows PowerShell Workflow automatically converts many of the Windows PowerShell cmdlets to activities when it runs a workflow. 在 Runbook 中指定其中一個 Cmdlet 時,對應的活動是由 Windows Workflow Foundation 執行。When you specify one of these cmdlets in your runbook, the corresponding activity is run by Windows Workflow Foundation.

如果 Cmdlet 沒有對應的活動,Windows PowerShell 工作流程會自動在 InlineScript 活動內執行 Cmdlet。If a cmdlet has no corresponding activity, Windows PowerShell Workflow automatically runs the cmdlet in an InlineScript activity. 某些 Cmdlet 會受到排除,除非您明確在 InlineScript 區塊中將其納入,否則無法用在工作流程中。Some cmdlets are excluded and can't be used in a workflow unless you explicitly include them in an InlineScript block. 如需詳細資訊,請參閱使用指令碼工作流程中的活動For more information, see Using Activities in Script Workflows.

工作流程活動共用一組通用參數來設定其作業。Workflow activities share a set of common parameters to configure their operation. 請參閱 about_WorkflowCommonParametersSee about_WorkflowCommonParameters.

位置參數Positional parameters

您無法對活動和工作流程中的 Cmdlet 使用位置參數。You can't use positional parameters with activities and cmdlets in a workflow. 因此,您必須使用參數名稱。Therefore, you must use parameter names. 請考慮會取得所有執行中服務的下列程式碼:Consider the following code that gets all running services:

Get-Service | Where-Object {$_.Status -eq "Running"}

如果您嘗試在工作流程中執行此程式碼,則會收到一則訊息,例如 Parameter set cannot be resolved using the specified named parameters.。若要針對此問題進行修正,請提供參數名稱,如下列範例所示:If you try to run this code in a workflow, you receive a message like Parameter set cannot be resolved using the specified named parameters. To correct for this issue, provide the parameter name, as in the following example:

Workflow Get-RunningServices
{
    Get-Service | Where-Object -FilterScript {$_.Status -eq "Running"}
}

已還原序列化的物件Deserialized objects

工作流程中的物件會還原序列化,這表示其屬性仍然可以使用,但並非其方法。Objects in workflows are deserialized, meaning that their properties are still available, but not their methods. 例如,請考慮下列 PowerShell 程式碼,其會使用 Service 物件的 Stop 方法來停止服務。For example, consider the following PowerShell code, which stops a service using the Stop method of the Service object.

$Service = Get-Service -Name MyService
$Service.Stop()

如果您嘗試在工作流程中執行此項目,您會收到錯誤訊息,指出 Method invocation is not supported in a Windows PowerShell Workflow.If you try to run this in a workflow, you receive an error saying Method invocation is not supported in a Windows PowerShell Workflow.

其中一個選項是將這兩行程式碼包裝在 InlineScript 區塊中。One option is to wrap these two lines of code in an InlineScript block. 在此情況下,Service 代表區塊內的服務物件。In this case, Service represents a service object within the block.

Workflow Stop-Service
{
    InlineScript {
        $Service = Get-Service -Name MyService
        $Service.Stop()
    }
}

另一個選項是使用會與方法具有相同功能的另一個 Cmdlet (若有)。Another option is to use another cmdlet that has the same functionality as the method, if one is available. 在我們的範例中,Stop-Service Cmdlet 會提供與 Stop 方法相同的功能,且您可能會在工作流程中使用下列程式碼。In our example, the Stop-Service cmdlet provides the same functionality as the Stop method, and you might use the following code for a workflow.

Workflow Stop-MyService
{
    $Service = Get-Service -Name MyService
    Stop-Service -Name $Service.Name
}

使用 InlineScriptUse InlineScript

當您需要執行一或多個命令做為傳統的 PowerShell 指令碼 (而不是 PowerShell 工作流程) 時,InlineScript 活動很實用。TheInlineScript activity is useful when you need to run one or more commands as traditional PowerShell script instead of PowerShell workflow. 在工作流程中的命令會傳送至 Windows Workflow Foundation 進行處理,而 Windows PowerShell 會處理 InlineScript 區塊中的命令。While commands in a workflow are sent to Windows Workflow Foundation for processing, commands in an InlineScript block are processed by Windows PowerShell.

InlineScript 使用如下所示的語法。InlineScript uses the following syntax shown below.

InlineScript
{
    <Script Block>
} <Common Parameters>

透過將輸出指派給變數,您可以從 InlineScript 傳回輸出。You can return output from an InlineScript by assigning the output to a variable. 下列範例會停止服務,然後輸出服務名稱。The following example stops a service and then outputs the service name.

Workflow Stop-MyService
{
    $Output = InlineScript {
        $Service = Get-Service -Name MyService
        $Service.Stop()
        $Service
    }

    $Output.Name
}

您可以將值傳入 InlineScript 區塊,但必須使用 $Using 範圍修飾詞。You can pass values into an InlineScript block, but you must use $Using scope modifier. 下列範例與前一個範例相同,不同之處在於服務名稱是由變數所提供。The following example is identical to the previous example except that the service name is provided by a variable.

Workflow Stop-MyService
{
    $ServiceName = "MyService"

    $Output = InlineScript {
        $Service = Get-Service -Name $Using:ServiceName
        $Service.Stop()
        $Service
    }

    $Output.Name
}

雖然 InlineScript 活動在某些工作流程中可能很重要,但它們不支援工作流程結構。While InlineScript activities might be critical in certain workflows, they do not support workflow constructs. 您應該只在必要時才使用它們,原因如下:You should use them only when necessary for the following reasons:

  • 您不能在 InlineScript 區塊內使用檢查點You can't use checkpoints inside an InlineScript block. 如果失敗發生在區塊內,其必須從區塊的開頭繼續。If a failure occurs within the block, it must resume from the beginning of the block.
  • 您不能在 InlineScriptBlock 區塊內使用平行執行You can't use parallel execution inside an InlineScript block.
  • InlineScript 會影響工作流程的延展性,因為它會保留 InlineScript 區塊的整個長度的 Windows PowerShell 工作階段。InlineScript affects scalability of the workflow since it holds the Windows PowerShell session for the entire length of the InlineScript block.

如需使用 InlineScript 的詳細資訊,請參閱在工作流程中執行 Windows PowerShell 命令about_InlineScriptFor more information on using InlineScript, see Running Windows PowerShell Commands in a Workflow and about_InlineScript.

使用平行處理Use parallel processing

Windows PowerShell 工作流程的優點之一是可平行執行一組命令,而不是如同一般的指令碼以循序方式執行。One advantage of Windows PowerShell Workflows is the ability to perform a set of commands in parallel instead of sequentially as with a typical script.

您可以使用 Parallel 關鍵字來建立具有多個同時執行之命令的指令碼區塊。You can use the Parallel keyword to create a script block with multiple commands that run concurrently. 這會使用如下所示的語法。This uses the following syntax shown below. 在此情況下,Activity1 和 Activity2 將同時開始。In this case, Activity1 and Activity2 starts at the same time. 只有在 Activity1 和 Activity2 都已完成之後,Activity3 才會開始。Activity3 starts only after both Activity1 and Activity2 have completed.

Parallel
{
    <Activity1>
    <Activity2>
}
<Activity3>

例如,考慮下列 PowerShell 命令,它會將多個檔案複製到網路目的地。For example, consider the following PowerShell commands that copy multiple files to a network destination. 這些命令會循序執行,因此一個檔案必須完成複製才能開始複製下一個。These commands are run sequentially so that one file must finish copying before the next is started.

Copy-Item -Path C:\LocalPath\File1.txt -Destination \\NetworkPath\File1.txt
Copy-Item -Path C:\LocalPath\File2.txt -Destination \\NetworkPath\File2.txt
Copy-Item -Path C:\LocalPath\File3.txt -Destination \\NetworkPath\File3.txt

下列工作流程會平行執行這些相同的命令,讓它們在相同的時間全部開始複製。The following workflow runs these same commands in parallel so that they all start copying at the same time. 只有在全部複製之後,才會顯示完成訊息。Only after they are all copied is the completion message displayed.

Workflow Copy-Files
{
    Parallel
    {
        Copy-Item -Path "C:\LocalPath\File1.txt" -Destination "\\NetworkPath"
        Copy-Item -Path "C:\LocalPath\File2.txt" -Destination "\\NetworkPath"
        Copy-Item -Path "C:\LocalPath\File3.txt" -Destination "\\NetworkPath"
    }

    Write-Output "Files copied."
}

您可以使用 ForEach -Parallel 建構來並行處理集合中每個項目的命令。You can use the ForEach -Parallel construct to process commands for each item in a collection concurrently. 會以平行方式處理集合中的項目,而循序執行指令碼區塊中的命令。The items in the collection are processed in parallel while the commands in the script block run sequentially. 此程序會使用如下所示的語法。This process uses the following syntax shown below. 在此情況下,Activity1 將與集合中的所有項目同時開始。In this case, Activity1 starts at the same time for all items in the collection. 針對每個項目,Activity2 會在 Activity1 完成之後開始。For each item, Activity2 starts after Activity1 is complete. 只有在 Activity1 和 Activity2 已完成所有項目之後,Activity3 才會開始。Activity3 starts only after both Activity1 and Activity2 have completed for all items. 我們使用 ThrottleLimit 參數來限制平行處理原則。We use the ThrottleLimit parameter to limit the parallelism. ThrottleLimit 過高可能會造成問題。Too high of a ThrottleLimit can cause problems. ThrottleLimit 參數的理想值取決於您的環境中的許多因素。The ideal value for the ThrottleLimit parameter depends on many factors in your environment. 以較小的值開始,並嘗試不同的遞增值,直到找到適合您特定情況的值為止。Start with a low value and try different increasing values until you find one that works for your specific circumstance.

ForEach -Parallel -ThrottleLimit 10 ($<item> in $<collection>)
{
    <Activity1>
    <Activity2>
}
<Activity3>

下列範例類似於先前的平行複製檔案範例。The following example is similar to the previous example copying files in parallel. 在此情況下,複製之後會對每個檔案顯示訊息。In this case, a message is displayed for each file after it copies. 只有在全部複製之後,才會顯示最後的完成訊息。Only after they are all copied is the final completion message displayed.

Workflow Copy-Files
{
    $files = @("C:\LocalPath\File1.txt","C:\LocalPath\File2.txt","C:\LocalPath\File3.txt")

    ForEach -Parallel -ThrottleLimit 10 ($File in $Files)
    {
        Copy-Item -Path $File -Destination \\NetworkPath
        Write-Output "$File copied."
    }

    Write-Output "All files copied."
}

注意

我們不建議並行執行子 Runbook,因為這可能會提供不可靠的結果。We do not recommend running child runbooks in parallel since this has been shown to give unreliable results. 有時候子 Runbook 的輸出不會出現,並且一個子 Runbook 中的設定會影響其他平行子 Runbook。The output from the child runbook sometimes does not show up, and settings in one child runbook can affect the other parallel child runbooks. VerbosePreferenceWarningPreference 等變數和其他變數可能不會傳播至子 Runbook。Variables such as VerbosePreference, WarningPreference, and others might not propagate to the child runbooks. 如果子 Runbook 變更這些值,它們可能無法在引動過程後正確地還原。And if the child runbook changes these values, they might not be properly restored after invocation.

在工作流程中使用檢查點Use checkpoints in a workflow

檢查點是工作流程目前狀態的快照,當中包含變數的目前值和在該點產生的任何輸出。A checkpoint is a snapshot of the current state of the workflow that includes the current values for variables and any output generated to that point. 如果工作流程結束時發生錯誤或已暫停,則在下一次執行時,會從其最後一個檢查點開始,而非從開頭開始。If a workflow ends in error or is suspended, it starts from its last checkpoint the next time it runs, instead of starting at the beginning.

您可以使用 Checkpoint-Workflow 活動來設定工作流程中的檢查點。You can set a checkpoint in a workflow with the Checkpoint-Workflow activity. Azure 自動化具有名為公平共用的功能,其中任何執行三小時的 Runbook 都會卸載,以允許其他 Runbook 執行。Azure Automation has a feature called fair share, for which any runbook that runs for three hours is unloaded to allow other runbooks to run. 最後,會重新載入已卸載的 Runbook。Eventually, the unloaded runbook is reloaded. 進行到此時,其會從 Runbook 所取得的最後一個檢查點繼續執行。When it is, it resumes execution from the last checkpoint taken in the runbook.

若要保證 Runbook 最終會完成,您必須在執行時間不到三小時的間隔中,新增檢查點。To guarantee that the runbook eventually completes, you must add checkpoints at intervals that run for less than three hours. 如果在每次執行時都新增檢查點,且如果 Runbook 在三個小時後由於錯誤而收回,則會無限期地繼續 Runbook。If during each run a new checkpoint is added, and if the runbook is evicted after three hours due to an error, the runbook is resumed indefinitely.

在下列範例中,Activity2 之後發生的例外狀況會造成工作流程結束。In the following example, an exception occurs after Activity2, causing the workflow to end. 工作流程再次執行時,其會先執行 Activity2,因為這個活動是緊接在設定的最後一個檢查點之後。When the workflow is run again, it starts by running Activity2, since this activity was just after the last checkpoint set.

<Activity1>
Checkpoint-Workflow
<Activity2>
<Exception>
<Activity3>

在活動可能容易發生例外狀況,且不應在工作流程繼續執行之後重複執行時,在工作流程中設定檢查點。Set checkpoints in a workflow after activities that might be prone to exception and should not be repeated if the workflow is resumed. 例如,您的工作流程可能會建立虛擬機器。For example, your workflow might create a virtual machine. 您可以在建立虛擬機器命令的前後設定檢查點。You can set a checkpoint both before and after the commands to create the virtual machine. 如果建立失敗,則再次開始工作流程時,命令可能會重複。If the creation fails, then the commands are repeated if the workflow is started again. 如果建立成功之後工作流程失敗,當工作流程繼續時,將不會再次建立虛擬機器。If the workflow fails after the creation succeeds, the virtual machine is not created again when the workflow is resumed.

下列範例會將多個檔案複製到網路位置,並在每個檔案後設定檢查點。The following example copies multiple files to a network location and sets a checkpoint after each file. 如果遺失網路位置,工作流程結束時會發生錯誤。If the network location is lost, then the workflow ends in error. 當它再次啟動時,會在最後一個檢查點繼續。When it is started again, it resumes at the last checkpoint. 只會略過已複製的檔案。Only the files that have already been copied are skipped.

Workflow Copy-Files
{
    $files = @("C:\LocalPath\File1.txt","C:\LocalPath\File2.txt","C:\LocalPath\File3.txt")

    ForEach ($File in $Files)
    {
        Copy-Item -Path $File -Destination \\NetworkPath
        Write-Output "$File copied."
        Checkpoint-Workflow
    }

    Write-Output "All files copied."
}

在您呼叫 Suspend-Workflow 活動或最後一個檢查點之後,使用者名稱認證就不會保存下來,因此您必須將認證設定為 Null,然後在呼叫 Suspend-Workflow 或檢查點後,再次從資產存放區擷取認證。Because user name credentials are not persisted after you call the Suspend-Workflow activity or after the last checkpoint, you need to set the credentials to null and then retrieve them again from the asset store after Suspend-Workflow or checkpoint is called. 否則,您可能會收到下列錯誤訊息︰The workflow job cannot be resumed, either because persistence data could not be saved completely, or saved persistence data has been corrupted. You must restart the workflow.Otherwise, you might receive the following error message: The workflow job cannot be resumed, either because persistence data could not be saved completely, or saved persistence data has been corrupted. You must restart the workflow.

下列同一個程式碼會示範如何在 PowerShell 工作流程 Runbook 中處理這種情況。The following same code demonstrates how to handle this situation in your PowerShell Workflow runbooks.

workflow CreateTestVms
{
    $Cred = Get-AzAutomationCredential -Name "MyCredential"
    $null = Connect-AzAccount -Credential $Cred

    $VmsToCreate = Get-AzAutomationVariable -Name "VmsToCreate"

    foreach ($VmName in $VmsToCreate)
        {
        # Do work first to create the VM (code not shown)

        # Now add the VM
        New-AzVM -VM $Vm -Location "WestUs" -ResourceGroupName "ResourceGroup01"

        # Checkpoint so that VM creation is not repeated if workflow suspends
        $Cred = $null
        Checkpoint-Workflow
        $Cred = Get-AzAutomationCredential -Name "MyCredential"
        $null = Connect-AzAccount -Credential $Cred
        }
}

注意

針對非圖形化 PowerShell Runbook,Add-AzAccountAdd-AzureRMAccountConnect-AzAccount 的別名。For non-graphical PowerShell runbooks, Add-AzAccount and Add-AzureRMAccount are aliases for Connect-AzAccount. 您可使用這些 Cmdlet,也可以在您的自動化帳戶中將您的模組更新為最新版本。You can use these cmdlets or you can update your modules in your Automation account to the latest versions. 即使您才剛建立新的自動化帳戶,可能還是需要更新您的模組。You might need to update your modules even if you have just created a new Automation account. 如果您使用以服務主體設定的執行身分帳戶進行驗證,則不必使用這些 Cmdlet。Use of these cmdlets is not required if you are authenticating using a Run As account configured with a service principal.

如需有關檢查點的詳細資訊,請參閱 加入檢查點至指令碼工作流程For more information about checkpoints, see Adding Checkpoints to a Script Workflow.

後續步驟Next steps