Replacing runbook PowerShell with runbook PowerShell workflow
While reading MSDN documentation, you probably came across multiple reasons to change your runbook PowerShell scripts to workflow. Even though this transition seems quite simple, that’s actually not the case. :) Here you can find a couple of things listed which are not that obvious and which are quite relevant for PowerShell workflow.
Checkpoints
Probably the strongest feature of PowerShell workflow are checkpoints. They are described as something quite simple to utilize, but that’s not actually true. Yes, you can simply put the line:
Checkpoint-Workflow
anywhere you want, but it doesn't mean everything will work fine.
1. Make sure you place checkpoints in the correct places, where they can make sense. Putting checkpoints everywhere will make your script slower and prone to errors. So, do it wisely. Put a checkpoint after an operation which shouldn't be repeated or which takes long time to be executed. For example:
$blobs = Get-AzureStorageBlob -Context $sourceContext -Container
$SourceContainer -MaxCount 1000 -ContinuationToken $continuationToken |
Select-Object Name,LastModified,ContinuationToken
# ...Process blobs in here...
Checkpoint-Workflow
2. When a checkpoint is requested, workflow foundation will serialize all currently present data to a database. So, if at any time, workflow is suspended and resumed, workflow foundation will recreate the last snapshot and your script will continue from the last checkpoint. Therefore, you need to set the most relevant variables for continuing to correct values. For example, if you process azure blobs in the loop, batch by batch, you have to redirect ContinuationToken object to the next batch before a new checkpoint is made.
do {
$blobs = Get-AzureStorageBlob -Context $sourceContext -Container $SourceContainer -MaxCount 1000 -ContinuationToken $continuationToken | Select-Object Name,LastModified,ContinuationToken
# ...Process blobs in here...
$continuationToken = $blobs[$blobs.Count - 1].ContinuationToken;
Checkpoint-Workflow
}
while ($continuationToken -ne $null)
3. Most likely some variables (objects) will be irrelevant for checkpoints. If objects are large, they could just slow down the serialization process or even produce serialization issues. Therefore, set to null those variables which will be recreated after a checkpoint or which are not relevant anymore! For example, the list of already processed blobs is irrelevant for the next checkpoint, since in the next loop iteration, the script will take another batch. Please take a look at the following example which illustrates all three points made in here regarding checkpoints.
do {
$blobs = Get-AzureStorageBlob -Context $sourceContext -Container
$SourceContainer -MaxCount 1000 –ContinuationToken
$continuationToken | Select-Object Name,LastModified,ContinuationToken
# ...Process blobs in here...
$continuationToken = $blobs[$blobs.Count - 1].ContinuationToken;
# Since we processed current batch, we don't want to persist
# this container when checkpoint is created
$blobs = $null
Checkpoint-Workflow
}
while ($continuationToken -ne $null)
Error handling
Is there something special about runbook workflow error handling? Well, there is. You could expect for the workflow script to stop when an exception/error occurs, but it won’t happen. By default, action in case of an error, is set to ‘Continue’. If you want to configure your workflow to stop its execution when an error occurs, you have to set the ErrorActionPreference variable to ‘Stop’ value. Do it, at the very beginning of your workflow script:
$ErrorActionPreference = "Stop"
In cases when you have multiple child runbook workflows invoked from your workflow script, make sure that you set this variable in each workflow script! Otherwise your child workflows will use the default value, which is ‘Continue’.
If specific error handling is required per cmdlet (workflow activity), so you don’t want to set behavior on a global script level, you can add the ‘ErrorAction’ parameter to specific cmdlet call. For example:
New-AzureAutomationSchedule -AutomationAccountName $accountName -Name $name -StartTime $startTime -ErrorAction "Stop"
It will stop the script execution if something goes wrong with the marked call. Switch ‘ErrorAction’ is quite useful if you want to log exception and stop the script execution. For example:
try { # ...do some work... }
catch [Microsoft.WindowsAzure.Commands.Storage.Common.ResourceNotFoundException] { Write-Error -Message $_.Message -ErrorAction Continue }
Logging
Workflow logging is configured through runbook settings accessible by the Azure portal. In there, through the “Logging and tracing” page, you can set log levels as you require. Bear in mind, if multiple child runbook workflows are invoked from another workflow, you will have to set logging for each workflow explicitly. Logging settings used for the main workflow which is invoked, do not apply to child workflows.