Windows PowerShell深入了解

Don Jones

Windows PowerShell 中有很多功能经常被许多管理员忽略。如果深入研究,您会发现很多意想不到的功能。实际上,我本人就经常发现自己会找到与自认为已非常了解的某个 Cmdlet 相关联的新功能。

在我教的 Windows PowerShellTM 课程中,我建议管理员为自己制定每日一个 Cmdlet 日历,这与您可能使用的每日一词日历相似。然后,工作日的每天早上(我让他们周末休息),他们可以用几分钟时间熟悉一个 Cmdlet 的完整功能。Windows PowerShell 附带了大约 130 个 Cmdlet,这意味着您只要坚持执行这个计划,那么只需要大约 6 个月的时间就可以了解 Windows PowerShell 的一切。到那时,您即可准备使用 Exchange Server 2007 的所有 Cmdlet。

在本月的专栏中,我想提供一些示例,说明您只要花费几分钟深入探索各个 Cmdlet 的功能,就可能会发现有价值的内容,并可能取得成果。

精致的 HTML 报表

一个在很大程度上没有得到充分利用的 Cmdlet 是 ConvertTo-HTML。这个智能的 Cmdlet 可以接受输入对象集合(服务、进程、Windows® Management Instrumentation (WMI) 对象等),并可将其转换为 HTML 表。接着您可以将 HTML 输送到 Out-File,然后就可以得到一个适合在 Intranet Web 服务器上发布的 HTML 页。例如,您可以安排以下简单的命令行在每天早晨运行:

Gwmi Win32_Service | Where { $_.StartMode –eq "Auto" –and $_.State –ne "Running" } | ConvertTo-HTML | Out-File C:\ServiceAlert.html

这将创建一个与图 1 内容相似的 HTML 报表,其中显示本应自动启动但尚未运行的服务。

Figure 1 An HTML report of services that aren't running

Figure 1** An HTML report of services that aren't running **(单击该图像获得较大视图)

当然,您可能想生成更吸引人的报表。幸运的是,ConvertTo-HTML Cmdlet 生成的是干净的 HTML,这意味着它不会在创建的 HTML 代码中嵌入任何格式。根据 HTML 的规则,应避免在 HTML 中嵌入格式(也就是应该尽可能减少嵌入格式),而应在外部级联样式表 (CSS) 中嵌入格式,并将 CSS 链接到 HTML。您可以使用 ConvertTo-HTML 创建该链接。

CSS 链接到 HTML 文件的 <HEAD> 部分。看一下 ConvertTo-HTML 的帮助,您会发现其语法中包括一些您可能忽略了的参数:

ConvertTo-Html [[-property] <Object[]>] [-inputObject <psobject>] [-body <string[]>] [-head <string[]>] [-title <string>] [<CommonParameters>]

–head 参数允许您指定要插入到脚本 <HEAD> 部分的其他 HTML 代码。现在我可以轻松修改我的一行代码,使其链接到现有的 CSS 文件,该文件包含我希望应用于 HTML 表的格式:

Gwmi Win32_Service | Where { $_.StartMode –eq "Auto" –and $_.State –ne "Running" } | ConvertTo-HTML -title "Services" -head "<link rel='stylesheet' href='styles.css' type='text/ css' />" | Out-File C:\ServiceAlert.html

在此,我使用了 –head 参数插入指向 CSS 文件的链接,该文件与输出 HTML 文件位于同一文件夹内。我还使用了 –title 参数设置网页的标题。最后的输出结果如图 2 所示。我在 Style.CSS 文件中使用的文本如下所示:

Figure 2 An HTML report that is formatted with a CSS file

Figure 2** An HTML report that is formatted with a CSS file **(单击该图像获得较大视图)

body { background-color:#EEEEEE; } body,table,td,th { font-family:Tahoma; color:Black; Font-Size:10pt } th { font-weight:bold; background-color:#CCCCCC; } td { background-color:white; }

筛选更轻松

本月 Cmdlet

本月我将介绍一个 Cmdlet 对:Start-Transcript 和 Stop-Transcript。它们都用于控制 Windows PowerShell 脚本记录,也就是将出现在控制台窗口中的所有内容写入您指定的文本文件中。使用起来非常简单。运行 Start-Transcript,并指定一个文件名开始此过程。然后,运行 Stop-Transcript 结束记录并关闭该文件。这为从使用临时外壳进入正式脚本提供了一个好办法 — 在外壳中使各个命令行正常工作之后,可以从您创建的记录文件复制并粘贴它们。当然,您也可以编辑该脚本记录,使其成为真正的脚本。我的最有价值同事 Jeffery Hicks 甚至编写了用于分析脚本记录并将其转换为 Windows PowerShell PS1 文件的脚本。您可以在以下位置找到此脚本:blog.sapien.com/current/2006/11/28/powershell-transcripts.html

现在,我们来看一下 Get-WMIObject Cmdlet。Windows PowerShell 内置帮助中列出的语法提示了它未被利用的功能:

Get-WmiObject [-class] <string> [[-property] <string[]>] [-namespace <string>] [-computerName <string[]>] [-filter <string>] [-credential <PSCredential>] [<CommonParameters>]

新 Windows PowerShell 用户常犯的一个错误是发出类似下面的 WMI 命令:

Gwmi Win32_NTLogEvent –comp Server2

此命令会检索 Server2 中的事件日志条目 — 所有事件日志条目。该任务会花费一段时间以供 Server2 进行处理和传输,而 Windows PowerShell 要利用这样一个大型集合,也会花费相当长的时间。

更好的解决办法是使 Server2 查找和发送您真正关心的事件。使用 WMI 查询语言 (WQL) 查询一定可以达到此目的。有人认为查询语法很难,但是利用 Windows PowerShell,您可以只使用 –filter 参数指定 WQL 查询的筛选部分:

Gwmi Win32_NTLogEvent –comp Server2 –filter "EventIdentifier=1024"

此命令会检索所有日志中事件 ID 为 1024 的所有事件。请注意,筛选条件使用 = 作为比较运算符,而不是 Windows PowerShell 的 –eq 运算符。这是因为筛选器只会传递到远程计算机的 WMI 服务进行处理,因此该条件需要使用 WMI 语法,而不是 Windows PowerShell 语法。

实际上,其他 Cmdlet 也具有 –filter 参数,如 Get-ChildItem,该 Cmdlet 还使用 Dir 和 Ls 等别名。在大多数情况下,–filter 参数将筛选条件直接传递到底层技术,生成我称之为源筛选的结果;与返回所有对象然后通过运行 Where-Object Cmdlet 筛选掉不需要的对象相比,这通常要快得多。

被忽略的 Cmdlet

这种每天学习一个 Cmdlet 的方法的确可以帮助您更好地了解您认为已经了解的 Cmdlet。但是使用每天一个 Cmdlet 日历还有另一个好缘由,就是这样可以完全避免遗漏某些 Cmdlet,采用其他方式则可能根本不会发现这些 Cmdlet。我最喜欢的一个,也是很多人都不使用的一个 Cmdlet,是 Resolve-Path。如果为该 Cmdlet 指定一个通配符路径,它将返回与该路径匹配的文件和文件夹名称的集合。它与 Get-ChildItem Cmdlet(也就是大家熟悉的 Dir 或 Ls 别名)相似,但是它不返回全部文件和文件夹对象,而是返回可以输送到其他 Cmdlet 以便进一步筛选或处理的简单字符串。它使用起来很简单:

Resolve-Path C:\P*

这个简单的命令行将返回诸如 C:\Program Files、C:\Processes.txt 的路径。图 3 显示了使用此 Cmdlet 的两个示例。

Figure 3 Using the handy, though overlooked, Resolve-Path cmdlet

Figure 3** Using the handy, though overlooked, Resolve-Path cmdlet **(单击该图像获得较大视图)

从头开始

如果您已经准备好开始每日一个 Cmdlet 的计划,请运行 Gcm(Get-Command 的别名)。将显示 Windows PowerShell 知晓的所有 Cmdlet 的列表,包括您通过管理单元添加的 Cmdlet,如 Exchange Server 2007 命令行管理程序、PowerShell Community Extensions 等。选择该列表中的第一个 Cmdlet(我选择的是 Add-Content),并阅读其帮助:

Help Add-Content –full

您需要的是完整的帮助(而不是较为简明的默认帮助),以便得到对每个参数的含义的完整描述,看到该 Cmdlet 的一些使用示例,并了解其他详细信息。花费一点时间试用该 Cmdlet。(您可能要使用虚拟机,以便不影响生产环境。)我建议您每个工作日留出 10 分钟的时间,而且每天大致在相同的时间,这样学习就可以成为一种习惯。用不了多长时间,您就可以深入了解 Windows PowerShell 提供的所有功能。

Don Jones 是 SAPIEN Technologies 的首席脚本权威和《Windows PowerShell: TFM》(SAPIEN Press, 2007) 的合著者。您可以通过 www.ScriptingAnswers.com 与他联系。

© 2008 Microsoft Corporation 与 CMP Media, LLC.保留所有权利;不得对全文或部分内容进行复制.