如何从父 Runbook(也是 7.2)中检索由“Start-AutomationRunbook”启动的 Azure PowerShell 子 Runbook (7.2) 的输出?

How can I retrieve output from Azure PowerShell child Runbook (7.2) started by 'Start-AutomationRunbook' from within parent Runbook (also 7.2)?

提问人:Wurstkopp 提问时间:11/3/2023 更新时间:11/7/2023 访问量:35

问:

标题说明了一切,我猜。

我正在尝试模块化我的 Runbook,我想做的就是使用内部自动化模块“Start-AutomationRunbook”启动子 RB 并返回结果。

这是我正在测试的示例代码:

家长RB:

$result = Start-AutomationRunbook -Name ChildRB
Write-Output $result

儿童RB:

$hello = 'Hello world!'
Write-Output $hello

但是,作业 ID 不会存储在$result中,而是将作业 ID 发送到控制台。

PowerShell Azure-Runbook

评论

0赞 Hugo 11/3/2023
是否与 Start-AzAutomationRunbook 相同?还是它们不同?我找不到第一个命令的文档Start-AutomationRunbook
0赞 Wurstkopp 11/3/2023
这正是我所面临的谜团。官方 MS 文档中只有几处提及:learn.microsoft.com/en-us/azure/automation/shared-resources/......

答:

0赞 Hugo 11/3/2023 #1

我假设这些工作方式类似于 PowerShell 中的作业。作业返回其 ID 而不是结果,因为它们的结果可能尚未准备就绪,因为作业仍在运行。

您可以将参数添加到 ,这将导致脚本此时等待,直到结果准备就绪。然后,您需要从作业对象中获取结果。只是:-WaitStart-AutomationRunbook

$Job = Start-AutomationRunbook -Name ChildRB -Wait

# Get the job results by returned ID
$Result = Receive-Job -Job $Job

# Print your output
Write-Output $Result

或者,您可以保持代码不变,并添加一个单独的部分,用于在作业准备就绪后收集结果。此方法的优点是可以并行运行作业,与第一个作业一样,它们一次运行一个作业。

这看起来像这样:

# Run a single runbook and gather its results
$Job = Start-AutomationRunbook -Name ChildRB

# Get the job object and wait on it.
Get-Job -Name "ChildRB" | Wait-Job

# Get the job results by returned ID
$Result = Receive-Job -Job $Job

# Print your output
Write-Output $Result

当然,上面的内容仍然只运行并等待一个命令,并且您没有利用并行可能性,在这种情况下,您可以执行如下操作,但请注意,处理并行作业的输出会变得越来越复杂:

# Imagine we have a list of RunBooks all with names like RunBook-1, RunBook-2 etc.
Foreach ($RunBookNumber in 1..10) {
  # Kick off all 10 of our runbooks in parallel
  Start-AutomationRunbook -Name Runbook-$RunBookNumber
}

# Wait for all of our jobs to be complete, we can supply a wildcard here.
$Jobs = Get-Job -Name "Runbook-*" | Wait-Job

# Loop through all the results from our jobs
Foreach ($JobResult in $Jobs) {
  # Receive-Job is what actually gets the result data, which is an array of every output returns in the order it was output.
  $Results = Receive-Job -Job $JobResult

  # Iterate through the array and print them all to the console.
  Foreach ($Result in $Results) {
    Write-Output $Result
  }
}

我在这里对 Start-AutomationRunbook 的工作原理做出了一些假设,但如果它类似于 Start-AzAutomationRunbook,那么我认为这应该有效。

评论

0赞 Wurstkopp 11/3/2023
第一个建议(添加“-Wait”参数失败:“Start-AutomationRunbook:行 |3 |$result = Start-AutomationRunbook -Name ChildRB -Wait |~~~~~ |找不到与参数名称'Wait'匹配的参数。现在尝试第二个想法。
0赞 Hugo 11/3/2023
@Wurstkopp这不是一个好兆头,这个命令肯定与当时的:(不同,只要它仍然返回作业对象,第二个想法就有望奏效Start-AzAutomationRunbook
0赞 Wurstkopp 11/3/2023
不。1) “接收作业:行 |8 |$Result = 接收作业 - 作业$Job |~~~~ |无法绑定参数“Job”。无法将“System.Guid”类型的“3a651db3-7c83-4915-97ad-e219770008b3”值转换为“System.Management.Automation.Job”类型。“ 2)”Get-Job:行 |5 |获取作业名称“ChildRB” |等待工作 |~~~~~~~~~~~~~~~~~~~~~~~ |该命令找不到作业,因为找不到作业名称 ChildRB。验证 Name 参数的值,然后重试该命令。
0赞 Wurstkopp 11/3/2023
不过,有一个命令“Wait-AutomationJob -Id <guid[]> [-TimeoutInMinutes <int>] [-DelayInSeconds <int>] [-OutputJobsTransitionedToRunning] [<CommonParameters>]”。我猜会玩那个。
0赞 Hugo 11/3/2023
是的,这看起来很有希望,尝试将所有工作命令换成那些希望它们只是等价的
0赞 Wurstkopp 11/7/2023 #2

我在这里发布了同样的问题:https://learn.microsoft.com/en-us/answers/questions/1417541/how-can-i-retrieve-output-from-azure-powershell-ch

我收到了以下答案,这确实有效:

若要从子 Runbook 获取作业输出,请使用 Az.Automation 模块中的 Get-AzAutomationJobOutput cmdlet。 下面是用于启动子 Runbook 的示例脚本,请等待它启动 完成,然后返回输出。

#Using Managed Identity for Authentication - START
# Ensures you do not inherit an AzContext in your runbook
Disable-AzContextAutosave -Scope Process

# Connect to Azure with system-assigned managed identity
$AzureContext = (Connect-AzAccount -Identity).context

# Set and store context
$AzureContext = Set-AzContext -SubscriptionName $AzureContext.Subscription -DefaultProfile $AzureContext
#Using Managed Identity for Authentication -END

$result = Start-AutomationRunbook -Name ChildRB

#wait for the job to complete else you may get empty result which creates confusion
Wait-AutomationJob -Id $result

#get the output from child runbook.
$out = Get-AzAutomationJobOutput $result -ResourceGroupName "new-autoAcc" -AutomationAccountName "autoacc" -Stream "Any"

write-output $out.Summary

请注意,“get-AzAutomationJobOutput”不是内部自动化 cmdlet(因此名称包含“Az”)。唯一的内部 cmdlet 为 可用在这里 - https://learn.microsoft.com/en-us/azure/automation/shared-resources/modules#internal-cmdlets

感谢 AnuragSingh-MSFT !!