Start-AzAutomationRunbook -Wait Is Not Enough

When working with Azure Automation Runbooks, it is quite common that one runbook needs to trigger another runbook and wait for the result before continuing the process.

The cmdlet Start-AzAutomationRunbook provides the parameter -Wait, which at first glance seems to solve exactly this problem. The command waits until the child runbook finishes. However, there is a major limitation: when using -Wait, the command does not return the JobId of the executed runbook.

This creates a problem. Without the JobId, it becomes difficult to reliably identify the job that was just started. A possible workaround would be retrieving the latest job from the automation account, but that approach has no guarantee that the returned job actually belongs to the runbook execution that was triggered.

A more reliable solution is to start the runbook without using the -Wait parameter. This way the command immediately returns the JobId. With that identifier available, the job can be monitored directly until it reaches a terminal state such as Completed, Failed, Stopped, or Suspended.

The advantage of this approach is that the automation can track the real status of the runbook. If the runbook fails, the caller receives the actual Failed state instead of assuming success. Additionally, it becomes possible to retrieve the runbook output, which can then be used for further processing.

Connecting to Azure Automation

PowerShell
$AzureContext = (Connect-AzAccount -Identity).context
Write-Output "Successfully connected to Azure using the system-assigned managed identity."
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext

Function to wait for the runbook job

PowerShell
function Wait-ChildRunbookJob {
param(
[string] $ResourceGroupName,
[string] $AutomationAccountName,
[guid] $JobId,
[int] $PollSeconds = 5,
[int] $TimeoutSeconds = 3600,
$DefaultProfile
)
$terminal = @('Completed','Failed','Stopped','Suspended')
$deadline = (Get-Date).AddSeconds($TimeoutSeconds)
while ($true) {
if ((Get-Date) -gt $deadline) {
throw "Timeout waiting for job $JobId after $TimeoutSeconds seconds."
}
$job = Get-AzAutomationJob `
-ResourceGroupName $ResourceGroupName `
-AutomationAccountName $AutomationAccountName `
-Id $JobId `
-DefaultProfile $DefaultProfile
if ($terminal -contains $job.Status) {
return $job
}
Start-Sleep -Seconds $PollSeconds
}
}

Function to retrieve runbook output streams

PowerShell
function Get-ChildRunbookStreams {
param(
[string] $ResourceGroupName,
[string] $AutomationAccountName,
[guid] $JobId,
[string] $Stream = 'Any',
$DefaultProfile
)
$headers = Get-AzAutomationJobOutput `
-ResourceGroupName $ResourceGroupName `
-AutomationAccountName $AutomationAccountName `
-Id $JobId `
-Stream $Stream `
-DefaultProfile $DefaultProfile
$records = $headers | Get-AzAutomationJobOutputRecord `
-ResourceGroupName $ResourceGroupName `
-AutomationAccountName $AutomationAccountName `
-JobId $JobId `
-DefaultProfile $DefaultProfile
$records
}

Starting the child runbook

PowerShell
$job = Start-AzAutomationRunbook `
-ResourceGroupName 'RG-Automation-Test' `
-AutomationAccountName 'aa-automation-test' `
-Name $RunbookName `
-RunOn 'HybridWorker01' `
-DefaultProfile $AzureContext
Write-Output "JobId is $($job.JobId)"

Waiting for completion

PowerShell
$job = Wait-ChildRunbookJob `
-ResourceGroupName "RG-Automation-Test" `
-AutomationAccountName "aa-automation-test" `
-JobId $job.JobId `
-PollSeconds 5 `
-TimeoutSeconds 3600 `
-DefaultProfile $AzureContext

Retrieving the output

PowerShell
$jobout = Get-ChildRunbookStreams `
-ResourceGroupName "RG-Automation-Test" `
-AutomationAccountName "aa-automation-test" `
-JobId $job.JobId `
-Stream 'Any' `
-DefaultProfile $AzureContext
$status = $job.Status
if($status -eq 'Completed'){
Write-Output "The job completed successfully"
}
elseif($status -eq 'Failed'){
Write-Output "The job failed"
}

Summary

By starting the runbook without the -Wait parameter and monitoring the JobId manually, it becomes possible to reliably track the runbook execution. This approach provides several advantages:

  • The JobId of the child runbook is always available
  • The exact runbook status can be retrieved
  • Failures can be handled correctly
  • The runbook output can be reused for further processing

This approach is especially useful when building larger automation scenarios where runbooks depend on each other and require reliable status handling.

Leave a comment