Windows Powershell
WMI 连接
文章来源:
Windows Powershell
WMI 连接
Don Jones
我在 VBScript 领域非常依赖的技术之一是 Windows Management Instrumentation
(WMI)。有趣的是,Windows PowerShell 与 WMI 有着密切的联系,这不仅仅是在技术意义上。Windows
PowerShell 的设计者 Jeffrey Snover 在创建
Wmic.exe 时也担任了重要角色,Wmic.exe 是 Windows Server®
2003 中与 WMI 一起使用的命令行工具。Wmic.exe 在许多方面表现了与 Windows PowerShell™
类似的工作方式(有关 WMIC 的详细信息,请参阅 John Kelbley 在 2006 年 9 月的《TechNet 杂志》上发表的文章,您可以在线访问,网址是 microsoft.com/technet/technetmag/issues/2006/09/WMIData)。
Windows PowerShell 以一致、基于对象的方式(与通过 Shell 的其他功能获得的方式相同)支持所提供的 WMI。与以前的技术(如 VBScript)相比,这使得 WMI 更容易学习和使用(尤其是在一些特殊情况下)。
WMI 入门
如果您阅读有关脚本的书籍和文章,几乎都会提到 WMI。不过,在实际使用 WMI 时,如果忘记其内部构造方式,则会感到非常迷茫,而且 WMI 的构造方式对于它在 Windows PowerShell 中的工作方式极其重要。
WMI 主要是一个组织类的系统,表示 Windows®
操作系统和其他基于 Windows
的硬件和软件产品的管理信息。类实际上就是对一些给定软件或硬件组件进程的属性和功能的抽象描述。例如,逻辑磁盘类可能描述具有一个序列号、一个固定的存
储容量、一定的可用容量等内容的设备。同时,描述 Windows 服务的类可能指定该服务有一个名称、可以启动和停止,以及指定其当前状态等。
在 WMI 中,类表示 WMI
可以管理的所有内容。如果 WMI 没有可用于某些内容的类,则它无法管理该组件。Microsoft 在
msdn2.microsoft.com/aa394554.aspx 中记录了核心 Windows WMI 类;其他产品(如 Internet
信息服务、SQL Server™)分别记录了它们的 WMI 类。
由于存在特别多的类,因此 WMI
将它们组织到命名空间层次结构中。例如,包含核心 Windows OS 类的命名空间称为 root\cimv2,而 Microsoft IIS
6.0 将其类存储在 root\MicrosoftIISv2 中。方便的是,root\cimv2 命名空间是 WMI 的默认命名空间(由
Windows PowerShell 共享的设置),这使得它可以更容易地与这些核心类一起使用。
“实例”是一种实际存在的类。例如,如果您
的计算机有两个逻辑磁盘,则会有 Win32_LogicalDisk 类的两个实例。如果在您的计算机上运行 50 个服务,在 WMI 上将会看到
Win32_Service 类的 50 个实例。使用 WMI 实际上就是请求 WMI
为您提供一个或多个实例,然后,要么检查这些实例的属性以发现您需要的管理信息,要么执行这些实例的方法来进行管理更改(例如启动或停止服务)。
WMI
使用客户端-服务器体系结构。Windows 2000 以后的每个 Windows 版本都内置了
WMI(后续版本扩展了可用类的数量),这意味着为您同时提供了 WMI 客户端和 WMI 服务器软件。在使用 WMI
时,您实际上是向在您关注的计算机上运行的 WMI 服务发送请求。该 WMI 服务检索您指定的 WMI 实例,并将其返回给您以供使用。这就是
Windows PowerShell 的作用,它简化了请求实例、返回实例和使用实例的过程。
获取 WMI 对象
WMI 类实例大致是指一些对象,因此在
Windows PowerShell 中检索这些实例的方法是 Get-WMIObject cmdlet,这很有意义。此 cmdlet
有一个方便的别名 gwmi,我将在大多数示例中使用这个别名。对于最简单的形式而言,您只需指定要检索的 WMI
类名称,然后悠闲地等着查看结果即可(请参见图 1)。在运行 gwmi win32_service
时,Windows PowerShell 连接到我本地计算机上的 WMI 服务(因为我没有指定其他计算机)并连接到 root\cimv2
命名空间(因为我没有指定其他命名空间)。Windows PowerShell
检索指定类的所有实例,由于我没有指示对这些实例执行其他任何操作,因此它将这些实例转换为文本表示形式。换句话说,Windows
PowerShell 获得这些对象,并将其生成可以阅读的文本。
图 1 在运行 gwmi win32_service 时,Windows PowerShell 以可读的文本格式返回指定类的所有实例
具体而言,Windows PowerShell 通过读取和显示所选类属性的名称和值将 WMI 对象转换为文本。对于 Win32_Service 类,它选择一组属性(共六个)。
实际上,Windows
PowerShell 通过此方式将所有对象转换为文本。它选择显示的属性大部分在一组 .format.ps1xml 文件中定义,该文件位于
Windows PowerShell 的安装文件夹中。这些格式定义文件经过 Microsoft
数字签名。尽管您可以提供自己的格式设置文件,但建议您不要更改这些文件。(在以后的专栏中,我将更详细地探讨这一主题。)
gwmi cmdlet
可以帮助您浏览计算机,查找有哪些可用类。例如,运行 gwmi –namespace "root\cimv2" –list
可以获得该命名空间中类的完整列表。但请记住,如果您在管理您的计算机,则仅与您计算机上的类相关;如果您在管理远程计算机,则将要查找该系统上可用的
类。对于本例而言,您需要使用 gwmi 的 –computer 参数连接远程计算机。例如,gwmi –namespace
"root\cimv2" –list –computer ServerA 将列出名为 ServerA 的远程计算机上 root\cimv2
命名空间中的所有类。
远程 WMI
在 Windows
PowerShell 的 1.0 版中,gwmi 可能是直接支持远程管理的唯一 cmdlet。这主要是由于远程控制构建在基础 WMI
体系结构中这一事实。而且,由于 Windows PowerShell 只是使用现有体系结构,因此它受制于该体系结构的安全功能。例如:
C:\> gwmi -namespace “root\cimv2” -computer
mediaserver -list
Get-WmiObject : Access is denied. (Exception
from HRESULT: 0x80070005 (E_ACCESSDENIED))
At line:1 char:5
+ gwmi <<<< -namespace “root\cimv2” -computer
mediaserver -list
PS C:\>
在本例中,我尝试连接到名为
MediaServer 的远程计算机(我对该计算机没有访问权限)。作为管理员,我应该有权使用此计算机的 WMI
服务,但我的本地工作站凭据似乎没有足够的权限。例如,我可能在一个不同的、不可信的域中登录,或者可能使用较少权限的帐户登录。幸运的是,gwmi
支持 –credential 参数,我可以通过该参数为我的 WMI 连接指定另外一组用户凭据。下面您将看到一个非常类似的示例:
gwmi win32_service –credential mydomain\administrator –computer mediaserver
我的凭据(更具体地说就是我的用户名)以 DOMAIN\Username 格式提供。
注意,您没有可以输入密码的地
方,Windows PowerShell 将提示这一点。Windows PowerShell
有意不提供在命令行输入密码的方法,因为这样会让您将密码硬编码到脚本文件,这无疑是一个安全风险。不过,您可以通过其他方法使用此
–credential 参数,即通过提前创建一种名为 PSCredential 的凭据对象。此命令为 Get-Credential
cmdlet:
$cred = get-credential mydomain\administrator
我在运行此代码时,系统仍然提示我输入匹配的密码。不过,这次创建的凭据对象存储在 $cred 变量中。如果我查看 $cred 的内容,我将看到名称而不是密码:
PS C:\> $cred
UserName
--------
mydomain\adminstrator
然后我可以随心所欲地重用该凭据对象:
gwmi win32_service –credential $cred –computer mediaserver
通过预定义一个可重用的凭据对象,这简化了到远程计算机
的重复 WMI 连接。不过这毫无意义,与 VBScript 的支持方式不同,Get-WMIObject cmdlet
目前不支持指定身份验证级别(也称模拟)。有关详细信息,请参见 msdn2.microsoft.com/aa389290.aspx。
自发现
我最喜欢的内容之一就是 Windows
PowerShell 不减少内容的难度。我向您介绍了 Windows PowerShell 如何只选择我查询的 Win32_Service
类的一组属性。不过,该 Shell 仍可以访问所有属性,甚至可以告诉您它们是什么。要执行此操作,只需将该对象(或多个对象)传输到
Get-Member cmdlet(或其别名 gm),如图 2 所示。
图 2 将一个对象传输到 Get-Member cmdlet 会告诉您可以访问哪些方法和属性 (单击该图像获得较大视图)
除了属性以外,该 Shell 还列出了可用的方法,这意味着我不必使用文档查看某个类的功能。我可以了解类本身提供了更改实例的配置、暂停服务和停止服务等任务的方法。
若要利用这些方法或显示其他属性,最容易的方法通常是将实例放入变量中:
$server = gwmi win32_operatingsystem
$server.reboot()
此示例将只检索 Win32_OperatingSystem 类的可用实例(该类在每台计算机上只有一个实例),并将其保存在 $server 变量中。然后,我将使用 $server 变量访问该实例的 Reboot 方法来重启计算机。使用该方法时一定要小心!
富查询语言
如果您在 VBScript
或其他技术下使用过 WMI,则可能习惯于使用 WQL(WMI 查询语言)编写的查询检索 WMI 类实例。其类似于 SQL
的语法使得检索特定实例(例如某个特定服务,而非某个给定类的所有实例)更加容易。幸运的是,gwmi 还可让您指定一个查询,如:
gwmi –query “select * from win32_service where name=’alerter’”
gwmi 的这一语法(在正式发布
Windows PowerShell 之前添加)非常有用,并使得迁移为其他用途开发的复杂 WMI
查询非常容易。而且,与往常一样,Windows PowerShell 将返回具有自己属性和方法的富对象,为您提供了访问 WMI
管理功能的完整权限。
WMI 的发展
将为 Windows
的未来版本继续开发 WMI,增加一些新类和功能。并继续将其添加到新的 Microsoft 产品中。尽管多数 Microsoft
产品尚未发布专门构建在 Windows PowerShell 上的版本,但其连接 WMI 的能力是使 Windows PowerShell
如今非常有用的最大好处之一。
我只是粗略地介绍了 WMI 的功能。但仍希望能借此激发您探索 Windows PowerShell 的兴趣,自己发现一些可用的功能。
阅读(4247) | 评论(3) | 转发(0) |