Windows PowerShell配置文件的力量

Don Jones

目录

外壳、主机和配置文件
使用配置文件?
创建自定义控制台
更多配置文件技巧
配置文件须知!

如果您定期阅读本专栏,那么至此您应该已经知道 Windows PowerShell 支持配置文件体系。它们实质是外壳在运行时自动执行的外壳脚本,具有 .ps1 文件扩展名。例如,它们提供了一种不错的方法来定义自定义别名。有了自定义别名后,在每次运行外壳时,配置文件都会自动定义您的别名,从而使它们在您使用外壳时随时可用。

外壳可以定义以下四种不同的配置文件:

  • 应用到所有外壳和计算机的所有用户的配置文件。
  • 应用到所有用户但仅应用到 Microsoft PowerShell 外壳的配置文件。
  • 应用到当前用户和所有外壳的配置文件。
  • 应用到当前用户且仅应用到 Microsoft PowerShell 外壳的配置文件。

“所有外壳”这一概念可能有点令人困惑。此术语源于 Windows PowerShell 的一些早期开发概念,它们并未真正应用到最终产品中。现在,术语“所有主机”可能会更准确一些。

外壳、主机和配置文件

其实,Windows PowerShell 本身就是一组 Microsoft .NET Framework 程序集。我喜欢将这一部分外壳称为 Windows Power­Shell 引擎,因为它包含通常被视为属于 Windows PowerShell 的功能。但是,没有内置的方法可供人们与此引擎交互。如果确实想要使用此外壳,必须通过宿主应用程序(或主机)加载此引擎。

您过去经常运行的 powershell.exe 应用程序就是一个此类主机。Windows PowerShell 2.0 社区技术预览版 (CTP) 随附的 gpowershell.exe 应用程序也是一个主机。主机和外壳之间的关系并不像我在这里说的这样简单,但这一简化的解释也完全涵盖了您所看到的行为。

必须要了解的是,如果通过基于文本的命令行界面与外壳进行交互,则您很可能使用的是 powershell.exe 主机。但即使您使用由其他应用程序(如 Exchange 管理外壳)所安装的快捷方式来启动外壳,这也同样适用。Exchange 管理外壳并不属于另一种外壳或宿主应用程序。实际上,它只是使用快捷方式启动的常规 powershell.exe 主机,此快捷方式可指定一组要预加载的管理单元和脚本。这些管理单元可在外壳中启用 Exchange 管理功能。但您使用的仍是相同的外壳。

powershell.exe 主机配置文件(在 Windows Vista 中)的位置如下所示:

  • %windir%\system32\Windows­PowerShell\v1.0\profile.ps1 用于计算机的所有用户和所有外壳。
  • %windir%\system32\Windows­PowerShell\v1.0\Microsoft.Power­Shell_profile.ps1 用于计算机的所有用户,但仅用于 Microsoft.PowerShell 外壳。
  • %UserProfile%\Documents\Windows­PowerShell\profile.ps1 仅用于当前用户和所有外壳。
  • %UserProfile%\Documents\WindowsPowerShell\Micro­soft.PowerShell_profile.ps1 仅用于当前用户和 Microsoft.PowerShell 外壳。

这些配置文件并不是在默认情况下创建的。必须在您手动创建后,它们才会出现。

每个宿主应用程序负责加载和执行正确的配置文件。如果某个特定宿主应用程序“决定”不加载任何配置文件,它实际上真可以这样做。配置文件的执行并非是由 Windows PowerShell 引擎自动实施的。

跟踪这一切的最简单方法是打开外壳,键入 $profile,然后按下 Enter 键。它将向您提供一个完整路径,外壳会试图使用它来作为被我称为“主”配置文件(它是针对每个用户且特定于外壳的配置文件)的路径。然后您可以创建或修改该脚本,而此脚本在每次外壳启动时都会执行。

使用配置文件

正如我之前建议的,配置文件的其中一个常见用途是定义自定义别名。或者,您可添加自定义 PSDrive(它们实质上是完全存在于 Windows PowerShell 中的映射驱动器)。不太常见的一种用途是根据您在环境中所使用的软件产品创建一种超外壳,它可以根据您的需求执行任何管理任务。要真正解释超外壳概念,首先需要了解一些背景信息。

Microsoft 中创建 Windows PowerShell 的产品组也负责许多其他核心管理技术,包括 Microsoft 管理控制台 (MMC)。MMC 具有与 Windows PowerShell 非常类似的工作原理。运行 mmc.exe 时,首先出现的是一个空白控制台,这对许多人来说都没什么用。您需要添加 MMC 管理单元才能创建一个能正常运行的控制台。

根据需要配置了控制台后,可将控制台保存在一个扩展名为 .msc 的文件中。利用这一保存的控制台文件,您可以随时快速重新加载自定义控制台。

许多管理员并不创建自定义 MMC 控制台,而是依赖于随所管理的产品一同安装的控制台。例如,Exchange Server 创建的控制台仅包含 Exchange Server 管理单元。“Active Directory 用户和计算机”是另一个包含单个管理单元的预创建控制台。

Windows PowerShell 的工作原理非常类似。随 Exchange Server 2007 管理工具一同安装的 Exchange 管理外壳图标实际上是指向 powershell.exe 的快捷方式,其中包含加载控制台文件的指令。外壳控制台文件的扩展名为 .psc1,内含要预加载的管理单元的列表(非常类似于 .msc 文件,其中包含 MMC 为您预加载的管理单元的列表)。但是,您并非一定要使用这些预创建的外壳控制台。您可以创建自定义控制台(就像在使用 MMC 时一样)并使用它来完成所有管理任务。配置文件在这一实现过程中起着关键作用。

创建自定义控制台

要创建自定义控制台,首先应查找要处理的每个管理单元的全名。确保所有必需的管理工具都已安装在计算机中。然后,在 Windows PowerShell 中运行 Get-PSSnapin –registered。这将列出所有已注册但却未加载的可用管理单元。然后创建或编辑相应的 Windows Power­Shell 配置文件。添加 Add-PS­Snapin 命令,加载希望始终可用的每个管理单元。这可能包括用于 Exchange Server、System Center 产品以及第三方管理单元(如 Power­Shell Community Extensions)的管理单元。然后保存配置文件(请记住,如果 Windows Power­Shell 执行策略需要,则对配置文件进行数字签名)并关闭外壳。重新打开外壳,它会自动加载配置文件中列出的所有管理单元。

另一种技术是将所有管理单元加载到外壳中(使用 Add-PSSnapin 和管理单元的名称),然后运行 Export-Console 创建一个 .psc1 控制台文件,其中包含当前正在使用的所有管理单元。然后,可使用这一 .psc1 控制台文件创建一个新的 Windows PowerShell 快捷方式,以指定 PSConsole­File 参数和自定义的 .psc1 文件。该快捷方式随后会使用您的控制台,并自动加载所有指定的管理单元。

更多配置文件技巧

我使用我的 Windows PowerShell 配置文件在每次外壳启动时执行许多其他有用的任务。以下是在我的系统上启动外壳时发生的一些情况:

  1. 我使用我的域管理员帐户运行 Get-Credential,并将结果存储在名为 $cred 的变量中。这将使 $cred 在整个外壳中都可用。然后可将其传递到各种 cmdlet(如 Get-WmiObject cmdlet)的 –credential 参数。由于 $cred 存储有密码,因此我可以直接使用这些 cmdlet 而不会被提示输入密码。
  2. 我运行 Cd C:\ 以便外壳在我计算机的 C:驱动器的根目录启动。
  3. 我运行 New-Alias of Out-File 以创建一个名为 "of" 的别名。这样,我可以使用 "of" 而不是使用 "Out-File"。我需要经常使用它,因此定义简短的别名非常方便。

我尝试在外壳的 HKLM:驱动器中创建一个测试密钥,HKLM 代表注册表的 HKEY_LOCAL_MACHINE 部分。如果出现错误,则我知道外壳是在没有提升权限的情况下启动的。通常我所做的工作需要提升权限,这只是我在执行重要工作之前预先了解自己是否具有提升权限的一种快速方法。

我定义一个名为 Ping-Address 的自定义函数,用于接收计算机名称或 IP 地址并根据计算机是否可 ping 返回 True 或 False 值。在我的工作中需要经常使用此函数,因此我在配置文件中对其进行了定义,以使其在我的外壳中全局可用。

本月 Cmdlet:Get-WmiObject

细心的读者可能已猜出我要介绍先前提过的 cmdlet,但我希望首先谈一谈它提供的一个很酷的变化功能。我常常看到有一些管理员试图通过使用以下技术从多台计算机(其名称列在一个文本文件中)来检索 Windows 管理规范 (WMI) 信息:

Get-Content c:\computers.txt | ForEach-Object 
  { Get-WmiObject Win32_Service –comp $_ }

尽管此技术非常有效,但实际您并不需要它,因为 Get-WmiObject 可接受 –computerName 参数的计算机名称数组。要实现相同的效果,您只需使用:

Get-WmiObject Win32_Service –comp (Get-Content
  c:\computers.txt)

将 Get-Content 命令放在括号中可强制外壳执行命令并将结果(计算机名称的数组)放入 –computerName 参数中。

配置文件须知!

请注意,powershell.exe 并不是加载 Microsoft.PowerShell 配置文件或所有外壳配置文件的唯一应用程序。许多提供 Windows PowerShell 支持(包括来自 SAPIEN Technologies 的 PrimalScript、来自 Quest Software 的 PowerGUI 以及来自 ShellTools 的 PowerShell Plus)的集成开发环境 (IDE) 也加载这些相同的配置文件,以提供与 powershell.exe 主机类似的体验。

加载大量管理单元的大型配置文件可能会导致这些应用程序的启动速度变慢,因为在准备就绪并且可以用于宿主应用程序之前,Windows PowerShell 引擎需要执行大量的指令。实际上,如果执行一个非常大的配置文件,即使是 powershell.exe 也需要经过一段时间才能启动起来。

使用相同名称来定义 cmdlet 的管理单元也可能会导致冲突。例如,如果两个管理单元都分别定义一个名为 Get-User 的 cmdlet,则 Windows PowerShell 不会执行任何一个 cmdlet,必须使用 cmdlet 的完全限定名来指定需要处理的具体目标。该完全限定名可能比较难看,因为管理单元名称可能会非常长。如果遇到此问题,我通常只是放弃同时加载这两个管理单元的想法。相反,我会仅加载在配置文件中最常用的管理单元,然后在需要加载并使用其他管理单元时使用单独的“全新”外壳。

Windows PowerShell 配置文件可为外壳提供大量附加的便利。但请记住,如果被某段恶意软件进行了恶意编辑,则配置文件也可能会造成大范围的破坏。要保护配置文件,您可以对它进行数字签名并对 Windows Power­Shell 进行配置以使用它的 AllSigned 执行策略,或者修改配置文件(所有)的 NTFS 文件权限以使常规用户帐户无法修改它们。

Don Jones 是《Windows PowerShell:**TFM》和《VBScript, WMI, and ADSI Unleashed》的作者。您可以通过 PowerShellCommunity.org 网站与他联系。