Windows PowerShell 工作流概念

重要

此版本的 Service Management Automation (SMA) 已终止支持。 建议 升级到 SMA 2022

Service Management Automation 的一种 Runbook 是基于 Windows PowerShell 工作流的。 本文简要概述了自动化 Runbook 中常见的工作流的关键功能。 有关工作流的完整详细信息可在 Windows PowerShell 工作流简介中找到。

适用于 Service Management Automation 和 Microsoft Azure Automation 的 Runbook 的结构相同,但这两种 Runbook 通常用于不同的资源。

Windows PowerShell 工作流

工作流是一系列编程的连接步骤,用于执行长时间运行的任务,或者要求跨多个设备或托管节点协调多个步骤。 与标准脚本相比,工作流的优点有:能够针对多台设备同时执行操作,并且能够从故障自动恢复。 Windows PowerShell 工作流是使用 Windows Workflow Foundation 的 Windows PowerShell 脚本。 虽然工作流使用Windows PowerShell语法编写并由 Windows PowerShell 启动,但它由 Windows Workflow Foundation 处理。

基本结构

Windows PowerShell 工作流以 Workflow 关键字开头,后跟括在大括号中的脚本正文。 工作流名称位于 Workflow 关键字的后面,如以下语法中所示。 工作流名称与 Automation Runbook 的名称匹配。

Workflow Test-Runbook
{
   <Commands>
}

若要将参数添加到工作流,请使用 Param 关键字,如以下语法中所示。 管理门户将提示用户在启动 Runbook 时提供这些参数的值。 此示例使用可选的 Parameter 属性,该属性指定参数是否为必需参数。

Workflow Test-Runbook
{
  Param
  (
   [Parameter(Mandatory=<$True | $False>]
   [Type]$<ParameterName>,

   [Parameter(Mandatory=<$True | $False>]
   [Type]$<ParameterName>
  )
  <Commands>
}

命名

工作流的名称应遵守“动词-名词”格式,该格式是 Windows PowerShell 的标准。 你可以参阅 Approved Verbs for Windows PowerShell Commands(Windows PowerShell Commands 批准使用的动词) 以了解批准使用的动词的列表。 工作流名称与自动化 Runbook 的名称匹配。 如果正在导入某个 Runbook,其文件名必须与工作流名称匹配,并且必须以 .ps1 结尾。

限制

有关限制以及 Windows PowerShell 工作流和 Windows PowerShell 之间的语法差异的完整列表,请参阅 脚本工作流和脚本之间的语法差异

活动

活动是工作流中的特定任务。 就像脚本由一个或多个命令构成一样,工作流由一个或多个按顺序执行的活动构成。 Windows PowerShell 工作流在运行工作流时,会将许多 Windows PowerShell cmdlet 自动转换为活动。 在 Runbook 中指定其中的某个 cmdlet 时,相应的活动实际上由 Windows Workflow Foundation 运行。 对于没有相应活动的 cmdlet,Windows PowerShell工作流会自动在 InlineScript 活动中运行 cmdlet。 有一组 cmdlet 被排除,并且不能在工作流中使用,除非将它们显式包含在 InlineScript 块中。 有关这些概念的详细信息,请参阅 在脚本工作流中使用活动

工作流活动共享一组公用参数来配置其操作。 有关工作流通用参数的详细信息,请参阅 about_WorkflowCommonParameters

集成模块

集成模块 是一个包含 Windows PowerShell 模块并能够导入到 Automation 的程序包。 Windows PowerShell 模块包含可在 Automation Runbook 中使用的 cmdlet。 Operations Manager 和 Azure 等产品和服务具有包含特定于其操作的 cmdlet 模块。

导入 Automation 的集成模块自动对所有 Runbook 可用。 由于自动化基于 Windows PowerShell 4.0,因此它支持自动加载模块,这意味着可以使用已安装模块中的 cmdlet,而无需使用 Import-Module 将其导入脚本。

可以将任何 Windows PowerShell 模块导入到 Automation 中,只要可在单一文件夹中找到该模块的所有依赖项。 如果模块依赖于不在默认路径中的注册表设置或文件,则可以导入该模块,但它很可能不起作用,因为自动化无法找到其依赖项。 具有外部依赖项的模块可用于 Runbook 中,方法是将它们安装到使用的另一台主机上,然后使用 InlineScript 脚本块访问它们。

通过 Service Management Automation,你可将具有外部依赖项的模块安装在每个辅助角色服务器上以进行使用。 虽然这些模块中的 cmdlet 可以在 Runbook 中使用,但自动化不会发现它们来支持诸如插入活动向导之类的功能。 为了使用此功能,你可以使用 New-SmaPortableModule cmdlet 创建一个便携模块。 此 cmdlet 创建一个模块,该模块为其每个 cmdlet 包括一个存根,并可导入到 Automation 中。 当 Runbook 使用其中一个 cmdlet 时,存根会将调用重定向到外部模块中的实际 cmdlet。 该模块必须安装在每个 Worker 服务器上,否则调用将失败。

并行执行

Windows PowerShell 工作流的一个优点是能够与典型脚本一样并行而不是按顺序执行一组命令。 这一点在 Runbook 中特别有用,因为它们可能会执行要花很长时间才能完成的多个操作。 例如,Runbook 可能会设置一组虚拟机。 可以同时执行操作,而不是按顺序执行每个预配过程,从而提高整体效率。 只有当所有操作都完成后,Runbook 才会继续。

可以使用 Parallel 关键字创建可同时运行的含多个命令的脚本块。 这会使用如下所示的语法。 在这种情况下,Activity1 和 Activity2 将同时启动。 只有在 Activity1 和 Activity2 已完成后,activity3 才会启动。

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

可以使用 ForEach-Parallel 构造同时处理集合中每个项的命令。 尽管脚本块中的命令按顺序运行,但集合中的项是并行处理的。 这会使用如下所示的语法。 在这种情况下,Activity1 将同时启动集合中的所有项。 对于每个项,Activity2 会在 Activity1 完成后启动。 只有在 Activity1 和 Activity2 完成所有项后,Activity3 才会启动。

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

Sequence 关键字用于按顺序运行 Parallel 脚本块中的命令。 Sequence 脚本块与其他命令并行运行,但块中的命令按顺序运行。 这会使用如下所示的语法。 在此例中,Activity1、Activity2 和 Activity3 将同时启动。 只有在 Activity3 完成后,Activity4 才会启动。 活动 5 将在所有其他活动完成后启动

Parallel
{
  <Activity1>
  <Activity2>

  Sequence
  {
   <Activity3>
   <Activity4>
  }
}
<Activity5>

检查点

检查点是工作流的当前状态的快照,其中包括变量的当前值以及到该点为止生成的任何输出。 Runbook 中要完成的最后一个检查点被保存到 Automation 数据库,以便即使出现故障,工作流也可继续。 Runbook 作业完成后,将删除检查点数据。

可以使用 Checkpoint-Workflow 活动在工作流中设置一个检查点。 如果将此活动包括在 Runbook 中,则会立即获取检查点。 如果 Runbook 由于错误而挂起,则在作业恢复后,它将从设置的最后一个检查点的位置处恢复。

在以下示例代码中,Activity2 之后发生错误,导致 Runbook 挂起。 作业恢复后,它将从运行 Activity2 开始,因为这正在设置的最后一个检查点后。

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

应在活动之后在 Runbook 中设置检查点,这些活动可能容易出错,如果 Runbook 恢复,则不应重复。 例如,你的 Runbook 可能创建虚拟机。 可以在命令之前和之后设置一个检查点以创建虚拟机。 如果创建失败,则命令会在 Runbook 恢复后重复。 如果创建成功,但 Runbook 稍后失败,则在恢复 Runbook 时不会再次创建虚拟机。

关于检查点的详细信息,请参阅向脚本工作流添加检查点

暂停 Runbook

你可以使用 Suspend-Workflow 活动强制 Runbook 自行暂停。 此活动将设置一个检查点,并使工作流立即挂起。 对于可能需要在运行另一组活动运行之前执行手动步骤的 Runbook,挂起工作流十分有用。

有关挂起工作流的详细信息,请参阅 Making a Workflow Suspend Itself(让工作流挂起自身)

InlineScript

InlineScript 活动在一个单独的非工作流会话中运行命令块,并将其输出返回到工作流。 尽管工作流中的命令将发送到 Windows Workflow Foundation 进行处理,但 InlineScript 块中的命令由 Windows PowerShell 处理。 该活动使用标准工作流通用参数,包括 PSComputerNamePSCredential,这些参数允许你指定代码块在另一台计算机上运行或使用备用凭据。

InlineScript 使用如下所示的语法。

InlineScript
{
  <Script Block>
} <Common Parameters>

InlineScript 在 Runbook 中的最常见用途是在另一台计算机上运行代码块。 如果 Runbook 中的 cmdlet 未安装在自动化中,或者操作仅有权在目标计算机上本地执行,则这是必需的。 下面的图表中阐释了这一点。

内联脚本关系图。

若要在另一台计算机上运行代码块,需要将 PSComputer 和 PSCredential 参数用于 InlineScript 活动。 通常在 Runbook 中使用 CredentialConnection 等全局资源为这些参数提供值。 下面的示例代码在由名为 MyConnection 的连接表示的计算机上运行一组命令。

$con = Get-AutomationConnection -Name 'MyConnection'
$securepassword = ConvertTo-SecureString -AsPlainText -String $con.Password -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $con.Username, $securepassword
InlineScript
{
  <Commands>
} -PSComputer $con.ComputerName -PSCredential $cred

尽管 InlineScript 活动在某些 Runbook 中可能很关键,但出于以下原因,只有在必要时才应使用它们:

  • 不能在 InlineScript 块中使用检查点。 如果块内出现故障,则必须从头开始恢复块。

  • InlineScript 会影响 Runbook 的可伸缩性,因为它包含 Windows PowerShell 会话的 InlineScript 块的整个长度。

  • 诸如 Get-AutomationVariableGet-AutomationPSCredential 之类的活动在 InlineScript 块中不可用。

如果你确实需要使用 InlineScript,应尽量减小其作用域。 例如,如果 Runbook 要循环访问某个集合,同时将相同的操作应用于每个项,则该循环应发生在 InlineScript 之外。 这将提供下列优势:

  • 你可在每个迭代后 检查 工作流。 如果作业挂起或中断并进行恢复,则循环将能够恢复。

  • 你可以使用 ForEach "Parallel 来并发处理集合项。

如果你确实要在 Runbook 中使用 InlineScript,请记住以下建议:

  • 你可以使用 $Using 作用域修饰符将值传入脚本。 例如,在 InlineScript 外部设置的名为 $abc 的变量将成为 InlineScript 内部的 $using:abc。

  • 若要从 InlineScript 返回输出,请将输出分配给变量,并将要返回的任何数据输出到输出流。 以下示例将字符串 hi 分配给名为 $output 的变量。

    $output = InlineScript { Write-Output "hi" }
    
  • 避免在 InlineScript 作用域内部定义工作流。 尽管某些工作流可能看起来正常运行,但这不是测试方案。 因此,你可能会遇到令人困惑的错误消息或意外的行为。

有关使用 InlineScript 的详细信息,请参阅在工作流中运行Windows PowerShell命令about_InlineScript

后续步骤