在 Runbook 中轻松使用 PowerShell V3 的“可靠会话”

几个星期前,Karl Prosser 发表了一篇有关结合使用 PowerShell V3 与 Orchestrator(英文)的有趣文章。上周在 MMS 上,我有机会坐下来并浏览了提供的 PowerShell V3 动手实验之一。在该实验中,我发现了有关远程访问和会话方面的新功能,我认为这对 Orchestrator Runbook 非常有用。

目前,在“运行 .NET 脚本”活动中运行 PowerShell 存在的问题是,该活动在每次运行时,都会创建一个 PowerShell 运行空间来运行该脚本(并创建/结束一个正在使用的远程会话),然后关闭该运行空间。没有任何跨多个活动扩展的运行空间(更不用说管道)。这意味着,您无法将 PowerShell 对象从一个活动传递到下一个活动,所有对象都将作为字符串返回发布的数据。Orchestrator CodePlex 网站(英文)上提供的 PowerShell IP 解决了 PowerShell 2.0 中的这一问题,它通过创建一个在后台运行的 WCF 服务以跨多个活动维护该会话,您只需使用“开始会话”和“结束会话”活动管理该会话。现在的唯一问题是必须始终在后台运行此服务。

我们在 VMM 和 DPM 集成包中通过让 Runbook 线程跨多个活动保持运行空间状态避免了此问题,但此方法也有其局限性,就是每次从一个活动(有多个传出链接)创建分支时,当前的线程将停止,并为每个链接启动一个新线程。因此,即使在自己的活动中,我们也需要解决必须重新创建大量运行空间的问题。

PowerShell V3 的妙处在于,我们现在可以在 PowerShell 中本机实现运行空间和会话的重用,无需创建和运行一个服务。在 PS V3 中,您可以创建一个会话,然后不限次数地断开和重新连接该会话,由远程计算机为您维护该运行空间,并可以缓冲连接之间的发生的任何输出。在本例中,我将向您介绍如何使用此进程创建并跨多个活动重用一个会话。首先,下面提供了一个示例 Runbook:

图像

我无需使用一个单独的活动来创建或关闭会话,这里仅将其作为一个示例。事实上,根本不用关闭会话。如果不使用,它最终会超时,但这不是一个理想的方法 – 当不再需要某些会话时,您不希望让它们处于打开状态,因为在超时之前,它们将用尽远程计算机上的会话配额。请始终作一个“良民”,并做好自己的清理工作。

下面是每个“运行 .NET 脚本”活动的内容:

创建会话

$retval = PowerShell {
$session = New-PSSession -ComputerName "{ServerName}" -Name " {RunbookID from "Initialize Data"} "
Get-PSSession
$null = Disconnect-PSSession -Name " {RunbookID from "Initialize Data"} "
}
$retval

设置变量

$retval = PowerShell {
$session = Connect-PSSession -ComputerName "{ServerName}" -Name " {RunbookID from "Initialize Data"} "
Invoke-Command -Session $session -ScriptBlock {$var1 = "foo"; $var1}
$null = Disconnect-PSSession -Name " {RunbookID from "Initialize Data"} "
}
$retval

获取变量

$retval = PowerShell {
$session = Connect-PSSession -ComputerName "{ServerName}" -Name " {RunbookID from "Initialize Data"} "
Invoke-Command -Session $session -ScriptBlock {$var1}
$null = Disconnect-PSSession -Name " {RunbookID from "Initialize Data"} "
}
$retval

关闭会话

$retval = PowerShell {
$null = Remove-PSSession -Name " {RunbookID from "Initialize Data"} "
Get-PSSession
}
$retval

我还在链接到 $retval 变量的每个名为“Output”的活动上创建了一个发布的数据属性。

下面是预期的操作:

  1. “创建会话”运行,“Output”包含“[PSSession]2860”。(因为该会话是一个对象,它将返回它可以返回的字符串表示形式)。
  2. “设置变量”运行。“Output”包含“foo”(因为我设置了该变量,然后将其输出到管道)
  3. “获取变量”运行。“Output”包含“foo”(显示该变量在整个断开连接的会话中保留)
  4. “关闭会话”运行。“Output”不包含任何内容(会话应关闭)。

亲自实施此操作

我不希望完全按照此方法实施此过程,即像这样跨多个活动复制该脚本。这将给维护带来很大麻烦。如果需要进行更改,我不必更改每个活动。较好的方法是编写一个包含所有必要逻辑的脚本,并且仅需使用参数调用该脚本。然后,您可以验证参数,很好地处理错误,自动设置会话等。我将编写该方法的一个示例,并很快将其发布出来。到那时,您可以下载 PowerShell V3 测试版并开始使用了!