了解適用於自動化 Runbook 的重要 Windows PowerShell 工作流程概念Learning key Windows PowerShell Workflow concepts for Automation runbooks

Azure 自動化中的 Runbook 會實作為 Windows PowerShell 工作流程。Runbooks in Azure Automation are implemented as Windows PowerShell Workflows. Windows PowerShell 工作流程類似於 Windows PowerShell 指令碼,但有一些顯著的差異可能會對新使用者造成混淆。A Windows PowerShell Workflow is similar to a Windows PowerShell script but has some significant differences that can be confusing to a new user. 雖然本文旨在協助您使用 PowerShell 工作流程撰寫 Runbook,但是除非您需要檢查點,否則建議您使用 PowerShell 來撰寫 Runbook。While this article is intended to help you write runbooks using PowerShell workflow, we recommend you write runbooks using PowerShell unless you need checkpoints. 在撰寫 PowerShell 工作流程 Runbook 時有許多語法差異,而這些差異需要更多的工作來撰寫有效的工作流程。There are several syntax differences when authoring PowerShell Workflow runbooks and these differences require a bit more work to write effective workflows.

工作流程是一連串的程式化、連接步驟,執行長時間執行的工作,或是需要跨多個裝置或受控節點協調多個步驟。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. 透過標準的指令碼工作流程的好處包括能夠同時對多個裝置執行動作,以及可自動從失敗復原的能力。The benefits of a workflow over a normal script include the ability to simultaneously perform an action against multiple devices and the ability to automatically recover from failures. Windows PowerShell 工作流程是使用 Windows Workflow Foundation 的 Windows PowerShell 指令碼。A Windows PowerShell Workflow is a Windows PowerShell script that uses Windows Workflow Foundation. 雖然工作流程是使用 Windows PowerShell 語法編寫,並由 Windows PowerShell 啟動,它是由 Windows Workflow Foundation 來處理。While the workflow is written with Windows PowerShell syntax and launched by Windows PowerShell, it is processed by Windows Workflow Foundation.

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

工作流程的基本結構Basic structure of a workflow

將 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 filename 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 to a script.

程式碼變更Code changes

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.

activitiesActivities

活動是工作流程中的特定工作。An activity is a specific task in a workflow. 就像指令碼是由一或多個命令所組成,工作流程是由序列中執行的一或多個活動所組成。Just as a script is composed of one or more commands, a workflow is composed of one or more activities that are carried out 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。For those cmdlets without a corresponding activity, Windows PowerShell Workflow automatically runs the cmdlet within an InlineScript activity. 有一組 Cmdlet 被排除,除非您明確在 InlineScript 區塊中將其納入,否則無法用在工作流程中。There is a set of cmdlets that are excluded and cannot be used in a workflow unless you explicitly include them in an InlineScript block. 如需這些概念的詳細資訊,請參閱 在指令碼工作流程中使用活動For further details on these concepts, see Using Activities in Script Workflows.

工作流程活動共用一組通用參數來設定其作業。Workflow activities share a set of common parameters to configure their operation. 如需有關工作流程通用參數的詳細資訊,請參閱 about_WorkflowCommonParametersFor details about the workflow common parameters, see about_WorkflowCommonParameters.

位置參數Positional parameters

您無法對活動和工作流程中的 Cmdlet 使用位置參數。You can't use positional parameters with activities and cmdlets in a workflow. 這都表示您必須使用參數名稱。All this means is that you must use parameter names.

例如,請考慮會取得所有執行中服務的下列程式碼。For example, consider the following code that gets all running services.

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

如果您嘗試在工作流程中執行這個相同的程式碼,您會接收到像「無法使用指定的具名參數解析參數集」的訊息。If you try to run this same code in a workflow, you receive a message like "Parameter set cannot be resolved using the specified named parameters." 若要修正這個問題,請提供參數名稱,如下所示。To correct this, provide the parameter name as in the following.

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

已還原序列化的物件Deserialized objects

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

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

如果您嘗試執行此工作流程,您會接收到錯誤,指出「Windows PowerShell 工作流程不支援方法引動過程」。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 區塊中,在此情況下 $Service 會是區塊內的服務物件。One option is to wrap these two lines of code in an InlineScript block in which case $Service would be 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 performs the same functionality as the method, if one is available. 在我們的範例中,Stop-Service Cmdlet 會提供與 Stop 方法相同的功能,並且您可以使用下面工作流程。In our sample, the Stop-Service cmdlet provides the same functionality as the Stop method, and you could use the following for a workflow.

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

InlineScriptInlineScript

當您需要執行一或多個命令做為傳統的 PowerShell 指令碼 (而不是 PowerShell 工作流程) 時, InlineScript 活動很實用。The InlineScript 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 may be critical in certain workflows, they do not support workflow constructs and should only be used when necessary for the following reasons:

  • 您不能在 InlineScript 區塊內使用檢查點You cannot use checkpoints inside an InlineScript block. 如果失敗發生在區塊內,它必須從區塊的開頭繼續。If a failure occurs within the block, it must be resumed from the beginning of the block.
  • 您不能在 InlineScriptBlock 內使用平行執行You cannot use parallel execution inside an InlineScriptBlock.
  • 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.

平行處理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 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. 您應該嘗試以較小的值開始,並嘗試不同的遞增值,直到找到適合您特定情況的值。You should try 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 completely 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. $VerbosePreference、$WarningPreference 等變數和其他變數可能不會傳播至子 Runbook。Variables such as $VerbosePreference, $WarningPreference, and others may not be propagated to the child runbooks. 如果子 Runbook 變更這些值,它們可能無法在引動過程後正確地還原。And if the child runbook changes these values, they may not be properly restored after invocation.

檢查點Checkpoints

檢查點 是包含變數的目前值和在該點產生的任何輸出的工作流程的目前狀態的快照。A checkpoint is a snapshot of the current state of the workflow that includes the current value for variables and any output generated to that point. 如果工作流程結束時發生錯誤或是擱置,下次執行時,就會從其最後一個檢查點開始,而不是從工作流程的開頭開始。If a workflow ends in error or is suspended, then the next time it is run it will start from its last checkpoint instead of the start of the workflow. 您可以使用 Checkpoint-Workflow 活動來設定工作流程中的檢查點。You can set a checkpoint in a workflow with the Checkpoint-Workflow activity. Azure 自動化的功能,稱為公平共用,其中卸載執行 3 小時內的任何 runbook,以允許其他 runbook 來執行。Azure Automation has a feature called fair share, where any runbook that runs for 3 hours is unloaded to allow other runbooks to run. 最後,卸載的 runbook 將會重新載入,並時,它會繼續執行,從 runbook 中採取的最後一個檢查點。Eventually, the unloaded runbook will be reloaded, and when it is, it will resume execution from the last checkpoint taken in the runbook. 為了確保將最後完成的 runbook,請您必須在執行少於 3 小時的時間間隔加入檢查點。In order to guarantee that the runbook will eventually complete, you must add checkpoints at intervals that run for less than 3 hours. 如果在每次執行期間加入新的檢查點,而且之後 3 小時內,因錯誤而取得收回的 runbook,然後 runbook 將會繼續無限期。If during each run a new checkpoint is added, and if the runbook gets evicted after 3 hours due to an error, then the runbook will be resumed indefinitely.

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

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

在活動可能容易發生例外狀況,且不應在工作流程繼續執行之後重複執行時,您應該在工作流程中設定檢查點。You should set checkpoints in a workflow after activities that may be prone to exception and should not be repeated if the workflow is resumed. 例如,您的工作流程可能會建立虛擬機器。For example, your workflow may create a virtual machine. 您可以在建立虛擬機器命令的前面和後面設定檢查點。You could set a checkpoint both before and after the commands to create the virtual machine. 如果建立失敗,若再次開始工作流程,命令可能會重複。If the creation fails, then the commands would be repeated if the workflow is started again. 如果建立成功之後工作流程失敗,當工作流程繼續時,將不會再次建立虛擬機器。If the workflow fails after the creation succeeds, then the virtual machine will not be 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 will resume at the last checkpoint meaning that 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 username 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. 否則,您可能會收到下列錯誤訊息︰工作流程作業無法繼續,原因是無法完整儲存持續性資料或儲存的持續性資料已損毀。 您必須重新啟動工作流程。Otherwise, you may 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 in your PowerShell Workflow runbooks.

workflow CreateTestVms
{
    $Cred = Get-AzureAutomationCredential -Name "MyCredential"
    $null = Connect-AzureRmAccount -Credential $Cred

    $VmsToCreate = Get-AzureAutomationVariable -Name "VmsToCreate"

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

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

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

重要

Add-AzureRmAccount 現在是 Connect-AzureRMAccount 的別名。Add-AzureRmAccount is now an alias for Connect-AzureRMAccount. 搜尋您的程式庫項目時,如果沒有看到 Connect-AzureRMAccount,便可以使用 Add-AzureRmAccount,或是在自動化帳戶中更新模組。When searching your library items, if you do not see Connect-AzureRMAccount, you can use Add-AzureRmAccount, or you can update your modules in your Automation Account.

如果您使用以服務主體設定的執行身分帳戶進行驗證,則不必這麼做。This 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