Windows PowerShell: 的高级的功能生命周期

Windows PowerShell 的高级的功能 — 称为脚本 cmdlet — 可以是有点令人困惑,但这是一种直接及其安装和清理功能的方法。

Don Jones

发生了一些我现场的 Windows PowerShell 类中的学生数的困惑日常点。 我希望这里更详细地了解它将帮助展开为您一些混乱以及。 主题是 Windows PowerShell,非正式地称为脚本 cmdlet 的高级的功能。 这种类型的函数的模板如下所示:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS {} END {} }

有几个有关这些 cmdlet 的混乱方面。 例如,在该形状中,已定义的输入的参数调用的计算机名。 这可以接受输入的管道。 这意味着您可以在两个截然不同的方法调用此函数。 首先,您可以有字符串通过管道传递给它,如从文本文件包含每行一个计算机名:

Get-Content names.txt | Do-Something

您还只是可以有一个或多个计算机名称直接传递到参数,而无需在所有使用管道:

Do-Something –computername SERVER1,SERVER2

在第一个示例中,该函数的开始块第一次执行。 然后,PROCESS 块执行一次为每个管道中的计算机名称。 $Computername 变量包含一次只能使用一个计算机名称。 最后,它们所有处理后,END 块执行一次。

在第二个示例中,开始和结束块永远不会执行。 PROCESS 块执行一次,并 $ 计算机名包含每个已传递给参数的名称。

因此很难执行安装和清理任务运行在这两种情况下,可以使这种行为的极端差异。 它还可能导致混乱有关处理带有 $ 计算机名称参数。 在第一个示例中它只包含一个值一次,而在第二,它将包含一个或多个值,具体取决于内容提供给 –computername 参数。 可以通过只需将放 ForEach 循环过程块内的解决 $computername 问题:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS { Foreach ($computer in $computername) { # use $computer here } } END {} }

此技术将保证 $计算机变量将包含只是一个计算机名称一次,因此它的 $ 计算机名 (而不是处理的更好。

安装和清理是有点棘手。 您不想直接在 PROCESS 块中的设置。 该块可以进行多次运行,当传入的对象。 另一方面,您不能直接插入开始块放置安装程序。 没有为管道不能运行的操作。 显然有许多方法无法处理的但这似乎是最好的:

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN { $setup_done = $false function DoSomethingSetup { set-variable -name setup_done -value $true -scope 1 } DoSomethingSetup } PROCESS { if (-not $setup_done) { DoSomethingSetup } Foreach ($computer in $computername) { # use $computer here } } }

这将利用所有的开始、 进程和结束块共享一个通用的范围,这意味着它们共享相同的变量的这一事实。 通过设置一个变量作为标志,您可以确保开始块的关键内容 — — 我的 DoSomethingSetup 函数 — 获取只能调用一次。

注意函数具有要用于一种专门技术标志设置成 $"DoSomethingSetup"一次真正您完成了安装任务。 因为它是一个函数,DoSomethingSetup 都有其自己的范围。 它通常不能更改中的某个变量,该范围之外的值。 您可以显式修改所需的变量使用设置变量 cmdlet。

清除任务对执行相同的目的是有点困难。 在第一个示例中,通过管道位置对象会被传递给执行某些东西,将运行 END 块。 您可以只放清理任务在那里。 但是,在第二个示例中为管道安排执行任何操作中,最终将永远不会运行。 PROCESS 块将只执行一次,因此它不一定是"知道"END 块不运行。

您不能只需调用 END 块内的某个函数的过程块。 当对象传入时,PROCESS 块将运行多次 — 并且不想不得不多次调用 END 块。

有一些狡猾的方法,可以解决问题,但较为简单的方法通常是最佳: 当您需要某种类型的清理活动 (如关闭数据库连接) 时,忘记了有关完全使用 BEGIN 和 END 块。 有假定它只打算运行一次,并只就在这里放置所有安装和清理过程块。

它可以是一种有点浪费 — — 可能会打开和关闭数据库连接重复,例如 — 但很有效。 它还消除了对具有代码内的有点儿古怪和硬按照 perambulations 的需要。

编程这些函数来处理管线和非管道方案可能会比较棘手。 在即将进行的某些列中,我将介绍一些其他人员解决此问题,所以您必须使用不同的选项在您自己的环境中的方法。

Denny Cherry

Don Jones 是一个 Microsoft MVP 奖收件人和"学习 Windows PowerShell 中每月的食谱"(Manning 出版物有限公司,2010年),旨在帮助生效 Windows PowerShell 与任何管理员一本书的作者。 此外,Jones 还提供公开和现场 Windows PowerShell 培训。 与他联系通过他的网站 ConcentratedTech.com

相关内容