收藏 分享(赏)

Powershell技术教程.doc

上传人:HR专家 文档编号:7510200 上传时间:2019-05-20 格式:DOC 页数:53 大小:1.25MB
下载 相关 举报
Powershell技术教程.doc_第1页
第1页 / 共53页
Powershell技术教程.doc_第2页
第2页 / 共53页
Powershell技术教程.doc_第3页
第3页 / 共53页
Powershell技术教程.doc_第4页
第4页 / 共53页
Powershell技术教程.doc_第5页
第5页 / 共53页
点击查看更多>>
资源描述

1、1PowerShell 强大的管理能力在经历了漫长的等待之后,PowerShell 终于已蓄势待发。这意味着该是 Windows 管理员提起注意的时候了。PowerShell 提供了也许是最简单且最灵活的方法来自动执行各种各样的管理任务,从而您的工作效率和效力都得到提高。但更为重要的是,Microsoft 正在 PowerShell 之上构建 Exchange Server 2007 和 System Center 2007 之类产品的图形管理控制台。这意味着您将能够从 PowerShell 内部执行几乎所有的管理任务。随着时间的推移,Microsoft 计划提高越来越多产品的管理能力。因此,

2、PowerShell 最终会成为用于管理几乎任何 Microsoft 服务器产品的第一个全能型工具。为了帮助您尽快入门,我将在此新设的专栏中定期探讨 PowerShell。请务必要下载一份软件。强大而又简便的功能顾名思义,PowerShell 是一个外壳,但与从 Windows NT 3.1 起就出现的命令提示符 (Cmd.exe) 不同。Cmd.exe 不会消失,但随着 PowerShell 的到来,几乎没有什么理由再继续使用 Cmd.exe。PowerShell 在使用方面与 Cmd.exe 并无多大不同,只是 PowerShell 的功能更为强大。与 Cmd.exe 一样,PowerSh

3、ell 具有内置的脚本编写语言,不过它比 Cmd.exe 原始的批处理语言更为灵活。灵活性是如何体现的呢?有了 PowerShell,您可以使用仅包括大约半打内置关键字的语言自动执行极其复杂的任务。既然我已提到了脚本编写,那么现在我可能就应该简单提一下安全性。PowerShell 得益于 Microsoft 过去十多年在安全性方面所取得的研究成果。默认情况下,PowerShell 不会运行脚本,只能交互式地用它来运行单个命令。如果您确实启用了脚本编写,则可令 PowerShell 仅运行经过数字签名的脚本。这些均有助于确保 PowerShell 不会成为下一个 VBScript 一种伟大的语言

4、,但它常被滥用来创建恶意脚本。VBScript 也不会退出历史舞台,但您可能会发现 PowerShell 对于许多不同的任务来说更易于使用。Cmd.exe 做到的事情,PowerShell 几乎都能做到。例如,您可以运行 ipconfig 并且会获得同样熟悉的输出。但是 PowerShell 会引入一整套新的命令,它们不是外部可执行文件。这些 cmdlet(发音为“command-let”)就内置于 PowerShell 之中(要了解对 PowerShell 使用入门最有用的 cmdlet,请参见侧栏的 “快速使用入门十大 Cmdlet”)。快速使用入门十大 CmdletGet-Command

5、 用于检索所有可用 cmdlet 的列表。Get-Help 用于显示有关 cmdlet 和概念的帮助信息。Get-WMIObject 用于通过 WMI 来检索管理信息。Get-EventLog 用于检索 Windows 事件日志。Get-Process 用于检索单个活动进程或活动进程的列表。Get-Service 用于检索 Windows 服务。Get-Content 用于读入文本文件,将每行视为一个子对象。Add-Content 用于将内容附加到文本文件。Copy-Item 用于复制文件、文件夹和其他对象。Get-Acl 用于检索访问控制列表 (ACL)。要获得 PowerShell 自带的

6、完整 cmdlet 列表,请访问 cmdlet 都以标准的“动词-名词”格式命名,这使其易于理解和记忆。例如,运行 Get-Command cmdlet 将会列出所有可用的 cmdlet。对于管理员来说最有用的 cmdlet 也许就是 Get-WMIObject。若您想要查明 Server2 正在运行哪个服务包,只需运行:Get-WMIObject Win32_OperatingSystem Property ServicePackMajorVersionComputer Server22要使用 VBScript 来发现同一信息,就得编写几行代码。利用 cmdlet 可以处理服务(Start

7、-Service、Stop-Service 等)、进程(Stop-Process 等)、文件(例如, Rename-Item、Copy-Item、Remove-Item、Move-Item)等等。其中许多 cmdlet 甚至还有快捷名称,称为别名。对于 Get-WMIObject 而言,您可以只键入 gwmi。运行 Get-Alias 将为您提供这些快捷名称的列表。为什么面向对象很重要PowerShell 在 Microsoft .NET Framework 上构建,所以它完全是面向对象的。通常,只有软件开发人员才会对此感到兴奋,但是就本处的情况而言,面向对象可以为管理员节省大量的时间。这是因

8、为管理员现在只需在基于文本的外壳内就能直接处理丰富的对象。请看以下示例:Get-Process | Sort-Object pm desc | Select-Object first 10这里只有一行,其中含有以管道分隔的三个不同的 cmdlet(稍后会对此进行详述)。第一个 cmdlet 检索所有正在运行的进程,然后将那些对象传递给或通过管道输送到 Sort-Object。第二个 cmdlet 基于每个进程对象的 pm(即物理内存)属性按降序对其进行排序。然后将进程对象的有序集合通过管道输送到 Select-Object,它将选取前十个对象进行显示。结果呢?此行简单命令会显示机器上的十大物理

9、内存使用者,如图 1 所示。这是一种极其有效的方法,借此可在执行某些故障排除时进行快速浏览。图 1 使用简单的 Cmdlet 进行故障排除 管道(在美式键盘上,该竖线字符通常位于反斜线按键上)的使用是 PowerShell 具有如此能力不可或缺的组成部分。使用此字符,可以将对象从一个 cmdlet 传递(或通过管道输送)给另一个,从而使每个 cmdlet 可以进一步提炼结果、设置结果的显示格式,等等。之所以能够采用这种机制,是因为每个 cmdlet 均会返回一个或多个对象,而非纯文本,这就使得后续 cmdlet 可以处理完整的对象。PowerShell 中的对象使用非常普遍,这全都仰仗于它的变

10、量。而且,您不必预先声明变量,只需在变量名称前放置一个美元符号 ($) 就可以开始使用它们了。尽管不是必需的,但您也可以将所要放入变量的数据类型告知 PowerShell。这使得 PowerShell 可以将变量映射到某一种极其强大的 .NET Framework 类型,从而为您提供诸多附加的内置功能。例如,假设您想要提示输入计算机名称并从该计算机中检索服务包版本,但是您不知道键入的计算机名称是否会包括两个反斜线(如 Server2)。由于您知道 Get-WMIObject cmdlet 不需要反斜线,因此您可以将计算机名称保存到一个字符串变量中,然后使用 Replace 方法以空字符串替换反

11、斜线,如下所示:string$c = Read-Host “Enter computer name“$c = $c.Replace(“,“)Get-WMIObject Win32_OperatingSystemProperty ServicePackMajorVersionComputer $c3已在 $c 变量中提供了 Computer 参数的值。该变量最初是作为字符串而创建的,因此它具有 .NET Framework 字符串类型的所有功能,包括 Replace 方法。当然,要了解所有这些功能需要花费一些时间,但是通过示例您应该很容易就能掌握这些功能。PowerShell 本身也有助于简化学

12、习过程。例如,如果您键入 $c = $c.(不要忘了句号)并按 Tab,PowerShell 将显示 Clone(),这是字符串类型的第一个方法。如果您一直按 Tab,PowerShell 将会循环列出所有可用的方法。实质上,当您这样做时,PowerShell 是在向您展示它所知道的字符串处理方法。在此给出一项更难的任务。从文件中读取计算机名称的列表(每行一个名称)并显示每台计算机的服务包号。在 VBScript 中,此项任务将需要一打或更多行的代码。在 Cmd.exe 中,您就得使用复杂的批处理文件。在 PowerShell 中,此项任务仅需一行:Get-Content “c:compute

13、rs.txt“ | foreach $_; gwmi Win32_OperatingSystem -propServicePackMajorVersion -comp $_ Get-Content cmdlet 读取 C:Computers.txt 的内容。文件的每一行均自成一个对象。此对象集合(即,计算机名称)通过管道输送到 foreach 命令(它其实就是 ForEach-Object cmdlet 的别名)。花括号内的命令会对通过管道送入的每个对象重复一次(在本例中就意味着它们对每个计算机名称都要运行一次)。特殊的 $_ 变量将包含当前对象(即,当前的计算机名称)。花括号内实际是两个命令

14、:第一个只是通过输出 $_ 的内容来显示当前的计算机名称。第二个是现已熟悉的 gwmi。结果将显示文件中所列出的每台计算机的服务包版本列表。所有这些都是用相对简单的一行命令完成的。请注意,Property 和 Computer 参数名已被缩写。PowerShell 仅需有足够的信息即可唯一地区分参数名。可读性与复用然而,编写一行命令和参数无助于可读性。PowerShell 允许您将其拆分成更具可读性的形式,您甚至不用编写脚本就能将其直接键入外壳。这就是它可能的形式:PS C: $names = get-content “c:computers.txt“PS C: foreach ($name

15、in $names) $name gwmi Win32_OperatingSystem -prop ServicePackMajorVersion -comp $name 这一次,文件的内容存储在变量 $names 中。本例仍使用了 foreach,但它不是通过管道进行输入的,因此必须告知它需要循环处理哪个对象集合以及将每个对象存储在哪个变量中,即 ($name in $names) 所指明的那一部分。其他方面大体相同,只要您一按 Enter,就会执行代码并显示结果。如果要重复使用此同一代码,只需将其制成函数即可。再次将以下内容直接键入到外壳中:PS C: function Get-Servi

16、cePacks ($file) $names = get-content $file foreach ($name in $names) 4 $name gwmi win32_operatingsystem -prop servicepackmajorversion -comp $name 如您所见,实际上并未做太多更改。只需将上一示例封入一个名为 Get-ServicePacks(与 PowerShell 的“动词- 名词”命名惯例保持一致)的函数即可。该函数现在具有一个名为 $file 的输入参数,该参数在 Get-Content cmdlet 中已被取代,这样便可在运行函数时指定另一不同

17、的文件。至此已定义了函数,运行它很简单,方法几乎与 cmdlet 一样,只需调用其名称并传递输入参数即可:PS C: Get-ServicePacks c:computers.txt图 2 显示了结果。其缺点在于此函数仅在该 PowerShell 实例运行期间才存在。一旦关闭外壳,该函数即会消失。您可以将该函数复制到您的 PowerShell 配置文件中,该配置文件是一种自动运行的脚本,它会在 PowerShell 每次启动时执行。这样做就使该函数在打开的每个 PowerShell 窗口中均可用。或者,如果需要,也可将该函数做成独立的脚本,然后只需键入其路径和文件名即可执行该脚本。图 2 运行

18、 Get-ServicePacks 函数的结果一切尽在于文件(或文件夹)PowerShell 决不只有函数和 cmdlet。让我们以文件管理为例来快速了解一下其中还蕴藏着什么别的内容。您可能对 Cmd.exe 中的驱动器和文件夹导航再熟悉不过了 键入 C: 可切换到 C 驱动器,键入 cd test 可转入 C:Test 文件夹。PowerShell 的工作方式完全相同,不过 cd 只是 Set-Location cmdlet 的别名。5尝试运行 Get-PSDrive,该 cmdlet 会列出所有可用的驱动器。除了常用的 C:、D:(也许还有 A:)驱动器之外,您还会发现一个名为 Cert

19、的驱动器、另一个名为 Env 的驱动器以及其他名为 HKCU 和 HKLM 的驱动器。实际上,PowerShell 将许多不同类型的存储资源均以“驱动器”形式公开,从而使得诸如本地证书存储区、环境变量和注册表等资源均可通过一个象文件那样为大家所熟悉的导航界面来获得。键入 Set-Location HKLM:(或 cd hklm:,如果您喜欢使用快捷方式)而后按 Enter,可转到 HKEY_LOCAL_MACHINE 注册表配置单元。如果要删除某个表项,可使用 del 将其删除,就像该表项是文件或文件夹一样(不过一定要非常小心,如果删除了必需的表项或是对注册表进行了不正确地修改,可能会发生严重

20、问题)。这一切灵活性均来自于提供程序,它们将资源(如注册表和证书存储区)映射成类似于文件系统那样的格式。Microsoft 计划通过另外的提供程序来扩展 PowerShell,例如,使您能够导航 Exchange Server 存储区,就像它是文件系统一样。这是一项非常重要的技术,重要性就在于它吸纳了 Windows 所使用的林林总总的存储库并使它们看起来全都相同,而且还使得它们都可以通过您已熟悉的命令和技术系统来进行管理。安全性设计我已提到过 PowerShell 在设计时很注重安全保护。PowerShell 中主要的安全功能是它的执行策略。默认情况下,此策略设置为“Restricted”

21、,您可以通过运行 Get-ExecutionPolicy cmdlet 来进行验证。在 Restricted 模式下,不能运行脚本。就这么简单。由于这是默认模式,因此刚出盒的 PowerShell 不能用来运行脚本。您可以使用 Set-ExecutionPolicy cmdlet 指定其他模式。我个人更偏爱 RemoteSigned 模式。在此模式下,可以运行未经数字签名的本地脚本(而非远程脚本),同时能够以最简单的方法开发和测试脚本。除非已使用受信任发布方所颁发的证书对脚本进行了数字签名,否则 AllSigned 模式不会运行任何脚本。最后,采用 Unrestricted 策略可运行任何脚本

22、。我建议切莫采用此策略,因为以此方式打开的 PowerShell 会运行可能伺机找上您计算机的恶意脚本。请注意,执行策略也可能受组策略支配,它会替代所有本地设置(如果组策略设置正要替代您的本地设置,Set-ExecutionPolicy 会向您发出警告)。另外,PowerShell 不会从当前目录运行脚本,除非您指定了该路径。这样设计是为了防止命令攻击。比如,某人创建了一个名为 IPConfig.ps1 的脚本(PS1 是 PowerShell 脚本文件的文件扩展名)。如果文件可在当前文件夹之外运行,则您可能会键入 ipconfig 而运行此用户所创建的脚本,可当时您其实是希望运行 Windo

23、ws 程序 Ipconfig.exe,这样就带来了风险。由于 PowerShell 不会在当前文件夹之外运行脚本,所以这种错误不可能发生。如果您的确想在当前文件夹之外运行脚本,只需指定路径即可:例如 .myscript。对当前文件夹的显式引用确保您知道自己正在运行脚本,而非外壳命令。PowerShell 还具有使实验变得更加安全的功能。例如,请考虑(但请勿尝试 )这个令人害怕的组合:Get-Process | Stop-ProcessGet-Process cmdlet 会创建进程对象的集合并通过管道将其输送到 Stop-Process cmdlet,而后者真的会将它们停止!这会导致在大约 5

24、 秒钟后出现蓝屏 STOP 错误,原因是终止了关键的 Windows 进程。但是,您可以通过添加非常方便的 Whatif 参数来看看将会发生什么情况,而不会令其真的发生:Get-process | Stop-Process -Whatif在 PowerShell 中运行此命令会产生一组语句,它们会告诉您 cmdlet 将会做什么,而不会真的让它们这样做。PowerShell 中的在线帮助系统(可通过 help 别名访问)尚未记载 Whatif 参数,但请记住它。它是一个很好的工具,用于测试脚本和 cmdlet 以检验其结果,而不会实际做出任何具有潜在危害性和破坏性的事情。总结在没有加入此 Po

25、werShell 版本的功能中,最重要的也许就是对 Active Directory 服务接口 (ADSI) 的支持。尽管 PowerShell 可以利用与 Active Directory 和其他目录服务配合工作的功能非常强大的 .NET 类,但它尚没有一个方便的 Get-ADSIObject cmdlet。这就给处理目录对象带来一点困难。此外,PowerShell 通常提供了多种不同的方法来执行同一任务。这样很好,但可能会令人在学习 PowerShell 时变得更加迷惑,因为对于任何给定的任务,您可能都会看到半打不同的处理方法示例。6PowerShell 构造上个月,我向您展示了将 Win

26、dows PowerShell 用于即时解决管理任务的方法 - 但没有编写任何文字资料。但是,Windows PowerShell 是一种优秀的交互式命令解释程序,您可以在开始利用它强大但脚本简单的语言时使用它的功能并自动执行更加复杂的任务。但首先您要问问自己:Microsoft 真的需要另一种脚本语言吗?毕竟,Microsoft 向我们提供了 KiXtart(一种登录脚本处理器)以及 Visual Basic Scripting Edition (VBScript)。但是,答案是肯定的。Microsoft 确实需要另一种脚本语言。我将解释原因。Windows PowerShell 语言需要简

27、单直观,这样管理员可以不经过太多训练就掌握它。它也需要相当灵活,这样就可以适应 Windows PowerShell 本身提供给用户的所有强大功能。因为 Windows PowerShell 是基于 Microsoft .NET Framework 的,所以它的脚本语法需要得到 .NET 的支持。在编写 Windows PowerShell 脚本语言时,设计师选择的实质上是高度简化的 C#(读作 C-Sharp,是 .NET Framework 附带的语言之一)。为什么不继续使用类似于 VBScript 的语法呢?实际上,Windows PowerShell 脚本语言与 VBScript 并没

28、有多大不同,只是与 C# 的语法更加接近,从某种意义上讲,PowerShell 是学习 .NET Framework 编程的踏脚石。如果您决定进阶到 Visual Studio 并开始编写 C# 应用程序,您的大部分 Windows PowerShell 脚本语法知识也将继续给您提供帮助。Windows PowerShell 脚本语言 - 或者就此而言,任何脚本语言 - 中最重要的一点是它的构造。 这些是特殊语言元素,允许 Windows PowerShell 执行逻辑比较并根据比较结果进行不同的操作或者允许不断地重复指令。进行逻辑思考逻辑比较是很多脚本语言构造的核心,Windows Powe

29、rShell 也不例外。比较实质上查看两个值或对象并计算以决定比较结果是 True 还是 False。例如,您可以问自己,“用户的密码有效期是否到今天截止?”如果今天到期结果为 True,否则为 False。注意我将 True 和 False 的首字母写成大写形式,因为在 Windows PowerShell 中它们是具有特殊含义的词。此处是一个您可以在 Windows PowerShell 中执行的真实的逻辑比较示例:PS C: $a = 1PS C: $b = 2PS C: $a -eq $bFalse我已经创建了名为 $a 的变量并将其设置为包含值 1。在 Windows PowerSh

30、ell 中,变量名总是以美元符号开头,因此容易辨认。从技术角度来说,= 是指赋值运算符,因为它用来赋值。接下来,我会创建第二个变量 $b 并将值 2 赋给它。然后进行实际的逻辑比较 - 我要求 Windows PowerShell 利用 -eq(相等)运算符来比较 $a 和 $b 的内容。PowerShell 执行比较,确定两个值不相等,并显示结果:False 。Windows PowerShell 运算符与您可能见过的其他脚本语言有点不同,甚至不同于 C#。大多数语言使用 = 运算符来检查是否相等以及执行赋值操作;而 Windows PowerShell 通过对每个函数采用专用的运算符来避免

31、混淆。图 1 显示 Windows PowerShell 比较运算符,以及您可能已经熟悉的其他语言(如 VBScript)中的相等运算符。Figure 1 PowerShell 比较运算符运算符名称 说明- 相等 测试值是否相等。其他语言可能使用 = 或 = 来测试相等。7eq-ne不等 测试不等。其他语言可能使用 字符。-lt 小于 测试一个值是否小于另一个值。其他语言可能使用 = 类似。-le小于或等于测试一个值是否小于或等于另一个值。与 VBScript 和其他语言中的 $a = “TechNet“PS C: $b = “technet“PS C: $a -eq $bTrue默认情况下,

32、比较运算符不区分大小写,意味着大写的 TechNet 将视为等价于“technet” 。那很方便,因为在大多数管理任务中您并不关心字母的大小写问题。但是,有时候您可能会关心,而您可以要求 Windows PowerShell 将字母 c 置于比较运算符之前以执行区分大小写的比较:PS C: $a -ceq $bFalse同样,如果您确实想知道或不确定 Windows PowerShell 是否会执行不区分大小写的比较,您可以通过预置字母 i 来强制它这样做:PS C: $a -ieq $bTrue只要记住逻辑比较总是产生两种结果之一:True 或 False。做决定8既然您知道了如何编写逻辑比

33、较,您可以开始在构造中使用它们。我将向您展示的第一个构造允许 Windows PowerShell 在比较的基础上做出决定。它称为 If 构造,并且有几种变形形式。以下是最简单的形式:PS C: if ($a -eq $b) Write-Host “They are equal“ They are equal此处有一些有趣的问题需要注意。首先,变量 $a 和 $b 仍然分别包含值 “TechNet“ 和 “technet“。我使用 If 关键字来作为构造的开头。之后,在括号中我输入了要执行的逻辑比较。接着是花括号,表示我将调用的条件代码(如果比较时返回的结果为 True,则为 Windows

34、PowerShell 将要执行的代码)的开始。您从之前的示例可以知道该比较确实返回 True,因此我期望执行条件代码。我键入我的条件代码 Write-Host “They are equal“,然后按 Enter。最后,我键入右花括号结束条件代码段,并敲击 Enter 两次。(第二次是在空白行上敲击 Enter,这让分析器知道我已经完成了编写并准备好执行代码。)注意该构造并不从脚本文件运行。我只需将它键入 Windows PowerShell 命令行。这使得 Windows PowerShell 在 Windows 的脚本世界里独一无二:脚本可以交互式地创建,也可以放入文件以做长久的存储。我一

35、键入左花括号并按 Enter,Windows PowerShell 就显示 提示符。那是它的表达方式,意思是“我识别出您位于构造中,并且我已准备好让您在构造内键入任何内容。”在我键入右花括号并敲击 Enter 两次后,Windows PowerShell 立即执行构造,确定其逻辑比较结果是 True 并执行条件代码。您可以看见该内容,因为 “They are equal“ 在 PowerShell 返回到其正常提示符前显示。使用 Windows PowerShell 来交互式地编写脚本允许您在将代码构建成为更长期的脚本前快速测试它们,使得学习和调试都更加容易。我要指出 Windows Powe

36、rShell 对按 Enter 这类的事并不是要求特别高。例如,这在功能上与上一示例相同:PS C: if ($a -eq $b) Write-Host “They are equal“ They are equal因为这些内容我都在一行上键入,所以 Windows PowerShell 不需要显示特殊的 提示符;它只需在我于行末按 Enter 时执行构造。Windows PowerShell 是如何知道可以执行构造了的呢?因为它在那个点处是完整的 - 已键入右花括号。我提到 If 构造的其他变形形式。以下是一个完整的示例,以其在 PS1 脚本文件而不是命令解释程序中的形式显示:if ($a

37、-eq $b) Write-Host “They are equal“ elseif ($a -lt $b) Write Host “One is less than the other“ else Write Host “One is greater than the other“9构造同样使用 If 关键字作为开头。但是,在比较结果为 False 的情况下,我使用 Elseif 关键字来提供了另一种比较。如果第二个比较结果也是 False,则最后一个关键字 Else 会提供将执行的最后一组代码。重复自身Windows PowerShell 包含几个用于反复执行代码的构造,直到比较结果为 T

38、rue 或 False。程序员调用这些循环构造。更好的是,其中最有用的一个循环构造可以枚举集合中的对象并为每个对象执行一行或多行代码。更确切地说,构造称为 foreach 构造,形式如下:PS C: $names = get-content “c:computers.txt“PS C: foreach ($name in $names) Write-Host $name don-pctestbed首先我要求 Windows PowerShell Get-Content cmdlet 检索 c:computers.txt 文件,这是我自己创建的文件,每行包含一个计算机名称。Windows Pow

39、erShell 将每一行作为对象来处理,因此文件实质上是包含这些对象的集合。集合以变量 $names 结束。使用 Foreach 关键字,我告诉 Windows PowerShell 通过利用变量 $names 在每次循环执行时表示当前对象来枚举 $names 集合。循环代码在花括号中。因此,对于文件中的每个名称,我都将输出到命令行。并且,如同您可以从构造后的输出看到的一样,那正是 Windows PowerShell 所做的。您可以看到这是如何在管理脚本中带来明显的益处的:例如,您可以轻松地构造服务器名称列表,并让 Windows PowerShell 依次从每一个中检索信息。实际构造那么,

40、让我们利用 If 构造和 foreach 构造来进行逻辑比较,并做一些有用的事情。我要快速检查一组服务器上的“Messenger”服务的状态。我期望在大多数服务器上服务将停止,因此我不想让 Windows PowerShell 列出所有其中的服务处于我所期望的状态的服务器;我只想让它列出 “Messenger” 服务实际已启动的服务器,因为我需要对这些服务器进行某些操作。我知道 Windows PowerShell Get-Service cmdlet 可以有助于检索我需要用于本地计算机的信息。但遗憾的是,它无法访问远程计算机,那才是我真正的目的。令人高兴的是,我也可以使用 Get-WMIOb

41、ject cmdlet,通过 Windows Management Instrumentation (WMI) 来访问相同的信息,这使我可以使用远程计算机。以下是脚本:$names = get-content c:computers.txtforeach ($name in $names) $svc = get-wmiobject win32_service -computer $name -filter “name=messenger“10if ($svc.started -eq $True ) write-host “$name has Messenger running“留意到第三行的

42、字符了吗?它告诉 Windows PowerShell 下一行是延续部分。它在整行如果不换行就无法置于库中这种情况下有用。还要注意 If 构造将 $svc.started 与 $True 比较。变量 $True 是 Windows PowerShell 中的特殊变量,表示布尔 True 值。(同伴变量 $False,表示布尔 False。)实际上,在那里我本可以走一些捷径:$names = get-content c:computers.txtforeach ($name in $names) $svc = get-wmiobject win32_service -computer $name

43、 -filter “name=messenger“if ($svc.started) write-host “$name has Messenger running“记住,If 构造的条件只需要为 True 或 False。通常,您通过比较两个值获得 True 或 False,就像我在该脚本的第一个版本中所做的那样。但是,由于“Started”属性为 True 或 False,因此无需将其与 True 或 False 比较。一种有用的工具至此您已经获得了一种利用构造来发挥作用,简单而有用的管理工具。无论您是交互式地将它键入 Windows PowerShell,还是在 PS1 文件中保存它以轻

44、松地复用,它都是一种检查各种计算机上服务状态的方便的工具,并且很好地演示了构造是如何有助于自动执行管理任务的。PowerShell 一次编写一行脚本在过去的专栏中,我强调了 PowerShell 是一种外壳这一事实。它应被交互式使用 与您可能已经很熟悉的 cmd.exe(或命令提示符)外壳并无不同。PowerShell 仍然支持脚本语言 一种比 cmd.exe 的批处理语言更稳定可靠的语言。并且它同某些语言(如 VBScript)一样功能强大(如果不如其功能强大的话)。但是,PowerShell 是一种交互式外壳的事实,使得编写脚本非常容易学习。实际上,您可以在外壳内部交互式地开发脚本,从而可

45、以一次编写一行脚本,并立即看到自己努力的成果。此迭代的脚本编写技术还使调试变得更加容易。由于您立即看到了脚本的结果,因此您就可以在脚本不能按预期方式运行时快速地对其进行修订。在此专栏中,我将向您介绍一个在 PowerShell 中进行交互式脚本编写的示例。我将创建一个脚本,该脚本从文本文件读取服务名称并将每个服务的启动模式设置为“Disabled”(禁用)。11我想要您从这次演练中领会到在小段代码中构建 PowerShell 脚本(而不是试图在大段代码中应对整个脚本)的概念。您可以采用需要完成的任何管理任务并将其分成组成自身的多段代码,然后确定使每段代码独立工作的方法。您将看到,PowerSh

46、ell 提供了将那些段代码联系起来的绝佳方法。并且您将发现,一次处理多个小段代码,您就会更轻松地开发最终脚本。从文件读取名称确定在 PowerShell 中读取文本文件的方法可能令人沮丧。如果我运行 Help *file*,那么我只能获得 Out-File cmdlet(用于将文本发送到文件)的帮助,而不会从中进行读取。根本没有帮助!但是,PowerShell cmdlet 名称遵循一种使用时对自己有利的逻辑。PowerShell 进行检索时,cmdlet 名称通常以 Get 开始。因此我在运行 Help Get* 显示出那些 cmdlet 后,就接着滚动列表并看到 Get-Content。看

47、来大有希望!因此我运行 Help Get-Content 以了解更多与 Get-Content 的用途有关的信息(见图 1),并且看来 Get-Content 将能够满足我的需求。图 1 运行 Help Get-Content 获得更多信息 PowerShell 将几乎每件事情都作为对象来处理,文本文件也不例外。文本文件从技术上说是行的集合,文件中的每一行都可充当一种独立对象。因此,如果我已经创建了一个名为 C:services.txt 的文本文件,并在其中填充了服务名称(在文件内部将每个名称放置在其本身的行上),PowerShell 可以使用 Get-Content cmdlet 逐个读取这

48、些名称。由于此次演练的目的是显示交互式开发脚本的方法,因此我首先只运行 Get-Content,为其赋予我的文本文件的名称,然后再查看发生了什么:PS C: get-content c:services.txtmessengeralerterPS C:正如所料,PowerShell 读取文件并显示名称。当然,只显示这些名称并不是我真正想要的,但现在我知道 Get-Content 正在以我所期望的方式工作。更改服务下一件我要做的事就是更改服务的启动模式。同样,我首先试图找到正确的 cmdlet。因此我运行 Help *Service*。此语句返回的列表很短,并且看起来只有 Set-Service

49、 cmdlet 才符合我的要求。在尝试将此 cmdlet 合并到脚本中之前,为了确保我了解它的工作方式,我要对其进行测试。运行 Help Set-Service,这将向我显示该 cmdlet 的工作方式,并且可通过快速测试进行确认:PS C: set-service messenger -startuptypedisabled12PS C:组合各部分现在我需要将从文件中读取服务名称的功能同 Set-Service cmdlet 相组合,并且这正是 PowerShell 的功能强大的管道功能起作用之处。使用此管道,一个 cmdlet 的输出可以作为输入传递给第二个 cmdlet。管道传递整个对象。如果将对象的集合放入管道,那么每个对象将单独通过管道。这意味着,Get-Content 的输出(请记住,这是对象的集合)可以通过管道输送到 Set-Service。因为 Get-Content 传递的是集合,所以集合中的每个对象(或文本行)将单独通过管道输

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报