• WMI 脚本


    什么是 WMI?
    WMI最初于 1998 年作为一个附加组件与 Windows NT 4.0 Service Pack 4 一起发行,是内置在 Windows 2000、Windows XP 和 Windows Server 2003 系列操作系统中核心的管理支持技术。基于由 Distributed Management Task Force (DMTF) 所监督的业界标准,WMI 是一种规范和基础结构,通过它可以访问、配置、管理和监视所有的 — 几乎所有的 Windows 资源。

    要掌握 WMI 的强大功能和范围,需要考虑以前(或者现在)如何管理并监视 Windows 工作站和服务器。您可能用过或仍在使用众多的图形化管理工具来管理 Windows 资源 — 例如磁盘、事件日志、文件、文件夹、文件系统、网络组件、操作系统设置、性能数据、打印机、进程、注册表设置、安全性、服务、共享、用户、组等等。

    尽管图形化工具提供了一种功能管理解决方案,它们所共有的东西是什么呢?一种答案是,在 WMI 之前,所有的 Windows 图形化管理工具都依赖于 Win32 应用程序编程接口(Application Programming Interfaces,APIs)来访问和管理 Windows 资源。为什么?因为在 WMI 之前,能够以编程方式访问 Windows 资源的惟一方法就是通过 Win32 API。这种情况使 Windows 系统管理员无法通过一种简便的方法利用常见的脚本语言来自动化常用的系统管理任务,因为大多数脚本语言都不能直接调用 Win32 API。通过提供一致的模型和框架,WMI 改变了这种情况 — 通过模型和框架,所有的 Windows 资源均被描述并公开给外界。最好的一点是,系统管理员可以使用 WMI 脚本库创建系统管理脚本,从而管理任何通过 WMI 公开的 Windows 资源!

    使用 Windows Script Host 和 Microsoft Visual Basic Scripting Edition (VBScript),或任何支持 COM 自动化的脚本语言(例如,ActiveState Corporation 的 ActivePerl),可以编写脚本来管理和自动化企业系统、应用程序和网络的下列方面:

    • Windows Server 2003、Windows XP 专业版和 Windows 2000 系统管理。您可以编写脚本来检索性能数据,管理事件日志、文件系统、打印机、进程、注册表设置、计划程序、安全性、服务、共享以及很多其他的操作系统组件和配置设置。
     
    • 网络管理。您可以创建基于 WMI 的脚本来管理网络服务,例如 DNS、DHCP 和启用 SNMP 的设备。
     
    • 实时健全监视。使用 WMI 事件订阅,您可以编写代码以在事件发生时监视并响应事件日志项,监视并响应文件系统、注册表修改及其他实时的操作系统更改。基本上对 WMI来说,WMI 事件订阅和通知是在 SNMP 环境中 SNMP 陷阱是什么。
     
    • Windows .NET 企业服务器管理。您可以编写脚本来管理 Microsoft Application Center、Operations Manager、Systems Management Server、Internet Information Server、Exchange Server 和 SQL Server。
     

    快速启动到 WMI 脚本

    为了让您对 WMI 脚本是什么有一些概念,让我们来看看一个表面看来不怎么重要的任务 — 检索安装在基于 Windows 的远程计算机中的物理内存的总量。在 WMI 之前,如果没有另外的第三方工具,是不能通过一个脚本来轻松完成这个任务的。实际上,在 WMI 之前,使用包括操作系统工具的工具确定安装在计算机中内存数量的惟一方法是通过系统属性对话框。今天,如果目标计算机上安装了 WMI,并且有计算机的管理员访问权限,您就可以使用一个 WMI 脚本来检索在远程 Windows 计算机上安装的物理内存量,如清单 1 中所示的一样简单。

    清单 1:使用 WMI VBScript 检索总物理内存

    strComputer = "."
    Set wbemServices = Getobject("winmgmts:\\" & strComputer)
    Set wbemObjectSet = wbemServices.InstancesOf("Win32_LogicalMemoryConfiguration")
    For Each wbemObject In wbemObjectSet
    WScript.Echo "Total Physical Memory (kb): " & wbemObject.TotalPhysicalMemory
    Next
    

    要运行清单 1 中的示例脚本,将其复制并粘贴到您最常用的文本编辑器中(notepad.exe 也可以),将分配给 strComputer 变量的值更改为域中一个有效的启用 WMI 的计算机,保存脚本(扩展名为 .vbs)


    有点不可思议,无须任何录入,您应该会看到目标计算机的物理内存量回显到控制台。

    现在,在你说“天哪!真的用六行脚本来检索一台计算机中的内存数量?”之前,让我们先礼貌地插几句话,因为至今尚不明显的是,您可以使用与在清单 1 中所演示的相同的基本步骤,从任何通过 WMI 公开的 Windows 资源检索配置和状态信息。

    假设您想要检索安装在一台远程计算机上的所有服务的名称、状态和启动类型。清单 2 中的示例脚本完全使用清单 1 中使用过的相同的基本步骤来完成。

    清单 2:使用WMI VBScript 检索服务信息

    strComputer = "atl-dc-01"
    Set wbemServices = Getobject("winmgmts:\\" & strComputer)
    Set wbemObjectSet = wbemServices.InstancesOf("Win32_Service")
    For Each wbemObject In wbemObjectSet
    WScript.Echo "Display Name:  " & wbemObject.DisplayName & vbCrLf & _
    "   State:      " & wbemObject.State       & vbCrLf & _
    "   Start Mode: " & wbemObject.StartMode
    Next

    托管资源

    托管资源是任意逻辑或物理组件,通过使用 WMI 进行公开和管理。
    可以使用 WMI 管理的 Windows 资源包括:计算机系统、磁盘、外围设备、事件日志、文件、
    文件夹、文件系统、网络组件、操作系统子系统、性能计数器、打印机、进程、注册表设置、安全性、
    服务、共享、SAM 用户和组、Active Directory、Windows 安装程序、Windows 驱动程序模式 (WDM)
    设备驱动程序,以及 SNMP 管理信息基 (MIB) 数据等。WMI 托管资源通过一个提供程序与 WMI 通讯。
    当开始编写脚本来与 WMI 托管资源交互时,您经常会看到一个术语实例,它被用于引用在运行中的脚本中的
    托管资源的虚拟表示形式。

    WMI 基础结构

    中间层是 WMI 基础结构。WMI 由三个主要组件构成:公共信息模型对象管理器(Common Information Model Object Manager,CIMOM)、公共信息模型(Common Information Model,CIM)储存库,以及提供程序。这三个 WMI 组件共同提供通过其定义、公开、访问和检索配置和管理数据的基础结构。虽然小,但是对编写脚本来说绝对不可或缺的第四个组件是 WMI 脚本库。

    WMI 提供程序

    WMI 提供程序在 WMI 和托管资源之间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从 WMI 托管资源请求信息,并发送指令到 WMI 托管资源。例如,清单 1 和清单 2 使用内置 Win32 提供程序来检索内存和服务相关信息。清单 3 使用内置的事件日志提供程序来从 Windows 事件日志检索记录。

    通过将托管资源公开给基于 WMI 标准的、统一访问模型的 WMI 基础结构,提供程序隐藏托管资源独有的实现详细信息。WMI 提供程序使用托管资源本机 API 与其相应的托管资源通讯,使用 WMI 编程接口与 CIMOM 通讯。例如,内置的事件日志提供程序调用 Win32 事件日志 API 来访问事件日志。

    基于 WMI 的可扩展体系结构,软件开发人员可以开发并集成附加提供程序来公开其产品特有的管理函数。监视 Exchange 连接器状态的 Exchange Server 2000 提供程序就是一个这样的示例。同样,Application Center、Operations Manager、Systems Management Server、Internet Information Server 和 SQL Server 都包含 WMI 提供程序。

    提供程序通常作为驻留在 %SystemRoot%\system32\wbem 目录中的动态链接库 (DLL) 实现。WMI 包括很多针对Windows 2000、Windows XP 以及 Windows Server 2003 系列操作系统的内置提供程序。内置提供程序(也被称为标准提供程序),从已知的操作系统源(如 Win32 子系统、事件日志、性能计数器、注册表等)提供数据和管理函数。表 1 中列出一些包含在 Windows 2000、Windows XP 和 Windows Server 2003 系列操作系统中的 WMI 提供程序。

    表 1:部分标准的 WMI 提供程序清单
    提供程序 DLL 命名空间 说明

    Active Directory 提供程序

    dsprov.dll

    root\directory\ldap

    将 Active Directory 对象映射到 WMI。

    事件日志提供程序

    ntevt.dll

    root\cimv2

    管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。

    性能计数器提供程序

    wbemperf.dll

    root\cimv2

    提供对原始性能数据的访问。

    注册表提供程序

    stdprov.dll

    root\default

    读取、写入、枚举、监视、创建、删除注册表项和值。

    SNMP 提供程序

    snmpincl.dll

    root\snmp

    提供对 SNMP MIB 数据的访问,并从 SNMP 托管设备捕获。

    WDM 提供程序

    wmiprov.dll

    root\wmi

    提供对 WDM 设备驱动程序中信息的访问。

    Win32 提供程序

    cimwin32.dll

    root\cimv2

    提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。

    Windows 安装程序提供程序

    msiprov.dll

    root\cimv2

    提供对已安装软件信息的访问。

    Windows XP 和 Windows Server 2003 包含很多附加的标准提供程序。


     

    浏览 CIM

    我们已经讨论了相当一部分的内容,但是还留有一个细节没有谈到,那就是如何确定哪些资源是通过 WMI 公开的。幸运的是,您可以使用多种不同工具来浏览 CIM 架构并检查 WMI 托管资源的类定义。

    WMI 控件。WMI 控件 (wmimgmt.msc) 是一个 Microsoft 管理控制台 (MMC) 管理单元,它允许您在本地或远程计算机上配置 WMI 设置。尽管您不能使用 WMI 控件浏览 CIM,但是可以使用该工具的“安全性”选项卡来确定在本地或远程计算机上可用的 CIM 命名空间。有关更多使用 WMI 控件的信息,参阅 Windows 2000 帮助或 Windows XP 帮助和支持中心内的 WMI 控件概述。

    WMI 测试器。WMI 测试器 (wbemtest.exe) 是一个用于与 WMI 基础结构交互的通用、图形化工具。您可以使用 WMI 测试器来浏览 CIM 架构并检查托管资源类定义。WMI 测试器还可用于执行与基于 WMI 的脚本执行的相同的操作,例如检索托管资源的实例和运行查询。WMI 测试器是在所有启用了 WMI 的计算机上默认的 WMI 安装的一部分,因此 wbemtest.exe 是一个出色的 WMI 学习和疑难解答工具。有关使用 WMI 测试器的信息,参阅 Windows XP 帮助和支持中心内的 WMI 测试器概述。

    WMI 命令行。作为 Windows XP 的一部分发布的 WMI 命令行工具 (wmic.exe) 提供一个到 WMI 基础结构的命令行接口。可以使用 wmic.exe 执行来自命令行的常见 WMI 任务,包括浏览 CIM 和检查 CIM 类定义。有关使用 WMI 命令行工具的信息,参阅 Windows XP 帮助和支持中心内的“使用 WMI 命令行 (WMIC) 工具”

    CIM Studio。作为 WMI SDK 的一部分,CIM Studio 提供一个基于 Web 的界面实现与 WMI 基础结构交互。与 WMI 测试器一样,您可以使用 CIM Studio 来浏览 CIM 架构、查看类定义并检索托管资源的实例。通过 CIM Studio 的超级用户界面可轻松查看类关系和关联,而且 CIM Studio 提供一个基本的搜索工具 — 它们是 WMI 测试器工具所不具备的两个功能。要使用 CIM Studio,您必需下载并安装 WMI SDK。您可以从 Windows Management Instrumentation (WMI) SDK 下载 WMI SDK。

    EnumClasses.vbs EnumInstances.vbs。Windows 2000 Server 资源工具箱包括很多利用了 WMI 的强大功能的脚本。这里所列出的三个脚本是常见脚本,可用于浏览 CIM 架构、查看类定义以及检索托管资源的实例。

    您应该查看的一些附加资源包括:

    WMI SDK 文档。WMI SDK 包含一个由标准的 WMI 提供程序提供的类的完整列表。您可以访问 MSDN 联机库中的 WMI SDK 文档

    TechNet 脚本中心。如果您愿意,可以把它叫做无用的废物,但是TechNet 脚本中心包含数百个来自即将推出的 System Administration Scripting Guide 中的基于 WMI 的示例脚本。

    WMI 测试器 (wbemtest.exe) 演练

    现在,您对可用于浏览和查看 CIM 的工具已经有了一些认识,让我们使用 WMI 测试器 (wbemtest.exe) 来检查 Win32_Process 类定义并修改清单 2,以便从在您的本地计算机上运行的进程检索一些属性。

    1.

    打开一个命令提示,键入 C:\>wbemtest.exe,按下 Enter 来开始 WMI 测试器工具。请注意,大部分按钮在主 WMI 测试器窗口上是被禁用的,这说明此时您没有连接到 WMI。

    2.

    单击 Connect? 连接到本地或远程计算机上的 WMI 服务。显示“连接”对话框,它提供一个标记为 Namespace 的文本输入区域,该区域默认值为 root\default。将 Namespace 区域的值更改为 root\cimv2,单击“连接”对话框的 Connect 按钮返回到主 WMI 测试器窗口。

    3.

    主窗口中左上角的命名空间标识符应该显示为 root\cimv2。请注意,所有的按钮现在都已启用,这说明在当前凭据环境下,您已经成功连接到本地主机上的 WMI。单击 Enum Classes? 打开“超类信息”对话框。

    4.

    在“超类信息”对话框中,不要填写 Enter superclass name 区域,单击 Recursive 选项,单击 OK 以枚举 root\cimv2 名称空间中定义的所有 CIM 类。

    此时,您可能应该正在查看一个列出了数百个类定义的“查询结果”对话框。类的数量主要取决于您正在运行的 Windows 的版本。例如,如果使用 Windows 2000,则您应该会看到大约 600 个类定义。如果运行 Windows XP,则您应该会看到大约 900 个类定义。

    请注意,列于“查询结果”对话框顶部的类是以两个下划线为开头的。这些是系统类。系统类是预定义的 CIM 类,支持内部 WMI 配置与操作,例如提供程序注册、命名空间安全性及事件通知等。现在,忽略系统类,向下滚动“查询结果”对话框直至看到以 CIM_ 开头的类。

    名称以 CIM_ 开头的类是由 DMTF 维护的核心与公共基类。继续向下滚动直至到达以 Win32_ 开头的类。

    名称以 Win32_ 开头的类是 Microsoft 扩展类,表示 Windows 特定的托管资源。如果这是您第一次检查 root\cimv2 命名空间,您可能希望熟悉 root\cimv2 命名空间中的类的完整集合,尤其是有 Win32_ 前缀的类。

    5.

    向下滚动“查询结果”对话框直至到达 Win32_Process 类,双击该类名打开 Win32_Process 对话框的对象编辑器。

    6.

    “对象编辑器”对话框显示被选定类的定义和实现的详细信息(属性和方法)。回忆一下我们之前讨论的内容 — 类定义是 WMI 可管理资源的蓝图。

    选择 Hide System Properties 复选框隐藏系统属性。剩余的 Win32_Process 属性表示您可以从在本地或远程计算机上运行的进程检索的信息。

    要完成您的 WMI 脚本练习,尝试去检索 NameHandleProcessID 属性。使用前面的三个清单之一作为模板,试着在进行到第 7 步之前运行脚本。

    要在本地计算机上运行脚本,将 strComputer 变量的值设置为“.”(引号内的一个单点)。

    7.

    在运行新创建的 GetProcesses.vbs 脚本之后,您可以用 WIMI 测试器验证脚本的结果。在 Win32_Process 对话框的对象编辑器中,单击 Instances。产生的查询结果对话框列出在计算机上运行的进程的实例。双击一个指定的进程实例,查看该实例的详细信息。



    命名空间使用

    那么,命名空间如何影响您的 WMI 脚本呢?每个 WMI 脚本都作为初始化连接步骤(上个月我们简要地讨论过)的一部分连接到一个命名空间,如下所示:

    strComputer = "."
    Set wbemServices = GetObject("winmgmts:\\" & strComputer)
    

    如上,如果没有指定目标命名空间,则脚本连接到由下列注册表设置识别的命名空间:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\Scripting\Default 命名空间

    默认的命名空间设置是 WMI 脚本,%PATH% 环境变量的默认设置是操作系统。当您通过命令提示提交了一个命令而没有指定命令的完全限定路径时,操作系统使用 %PATH% 环境变量来定位该命令的可执行文件。如果操作系统不能找到这个文件,就会产生错误。

    同样,当您在 WMI 脚本中检索一个托管资源时,如果没有指定命名空间,CIMOM(WMI 服务)就在默认的命名空间寻找该托管资源的蓝图(类定义)。如果 CIMOM 在默认的命名空间中找不到托管资源类定义,就会产生一个 WBEM_E_INVALID_CLASS (0x80041010) 错误。

    不要将默认的命名空间设置与 root\DEFAULT 命名空间相混淆。它们是不相关的,除非您将 root\DEFAULT 设置为您的默认命名空间。

    命名空间 root\cimv2 被初始配置为脚本默认的命名空间;但是,默认的脚本命名空间可以很容易地进行更改。因此,您应该始终在您的 WMI 脚本中标识一个托管资源的命名空间,而不是采用默认设置。如果上个月就遵照了我们自己的建议,所有 4 个清单(以及本文的清单 1 和 2)中的连接步骤就应该编写如下:

    strComputer = "."
    Set wbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    

    将目标命名空间添加到连接字符串会告诉 CIMOM 在 CIM 中到哪里去寻找托管资源类定义,很像完全限定路径告诉操作系统到底去哪里寻找一个文件。当您指定了目标命名空间,默认的命名空间就不使用了。

    管理脚本的默认命名空间

    您可以像清单 3 和清单 4中展示的那样,将 WMI 脚本库与 Win32_WMISetting 类结合使用来读取和更改脚本的默认命名空间。Win32_WMISetting 是一个为 WMI 服务的操作参数建模的动态类。可写的属性表示脚本的默认命名空间是 ASPScriptDefaultNamespace

    清单 3 使用了相同的 3 个 WMI 脚本编写步骤 — 连接、检索和显示 — 我们一直在使用的步骤,不过有一个明显的改变。正如前面建议的,我们在传递到 Microsoft Visual Basic Scripting Edition (VBScript) 的 GetObject 函数的 WMI 连接字符串中,指定 Win32_WMISetting 类的完全限定命名空间。那么,这里您会认为 Microsoft 没有遵循他们自己的建议。我们不但在清单 3 中遵循我们命名空间的建议,而且从此以后我们将限定命名空间。是的,如果想在您的 WMI 脚本中避免无效的类错误,它就是那么的重要。

    检索托管资源实例

    到现在为止,我们一直使用 SWbemServicesInstancesOf 方法来检索托管资源实例,如清单 1 中所示。

    清单 1. 使用 SWbemServices InstancesOf 检索服务信息

    strComputer = "."
    Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colSWbemObjectSet = objSWbemServices.InstancesOf("Win32_Service")
    For Each objSWbemObject In colSWbemObjectSet
    WScript.Echo "Display Name:  " & objSWbemObject.DisplayName & vbCrLf & _
    "   State:      " & objSWbemObject.State       & vbCrLf & _
    "   Start Mode: " & objSWbemObject.StartMode   & vbCrLf
    Next
    

    虽然 InstancesOf 的确获得了成功,但是您只想要实例或属性的一个子集的情形又怎么样呢?假设您想要优化实例和属性恢复到最小的网络流量。在这种情况下,您会非常高兴听到 WMI 支持大量强大的查询工具。

    查询 WMI 是向匹配一些预定义条件的托管资源发出请求的过程。例如,WMI 查询只能请求那些处于 Stopped(停止)状态的带有 StartMode of Auto(自动的启动模式)的服务。

    WMI 查询为检索托管资源实例及其属性提供了比 InstancesOf 方法更有效率的机制。WMI 查询只返回那些匹配查询的实例和属性,但是 InstancesOf 总是返回一个指定资源的所有实例以及每个实例的所有属性。同样,查询是在与对象路径中一致的目标计算机上进行的,而不是在运行脚本的源计算机上。因此,WMI 查询可以显著地减少像 InstancesOf 那样更低效率的数据检索机制造成的网络流量。

    要查询 WMI,使用 WMI 查询语言(WQL)构造一个查询字符串。查询字符串定义了必须被满足的条件来获得成功匹配的结果。在查询字符串定义后,查询使用 SWbemServicesExecQuery 方法提交到 WMI 服务。满足查询的托管资源实例以 SWbemObjectSet 集合的形式返回到脚本中。

    使用 WQL 和 ExecQuery 方法(而不是 InstancesOf)为创建只返回您感兴趣的项的脚本提供了灵活性。例如,您可以使用基本的 WQL 查询来返回一个给定托管资源的所有实例的所有属性,如清单 2 所示。这与 InstancesOf 方法返回的信息是一样的。如果比较清单 1 和 2,您会注意到第 3 行的粗体部分是两个脚本间唯一的差别。

    清单 2. 使用SWbemServices ExecQuery 检索服务信息

    strComputer = "."
    Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM Win32_Service")
    For Each objSWbemObject In colSWbemObjectSet
    WScript.Echo "Display Name:  " & objSWbemObject.DisplayName & vbCrLf & _
    "   State:      " & objSWbemObject.State       & vbCrLf & _
    "   Start Mode: " & objSWbemObject.StartMode   & vbCrLf
    Next
    

    您也可以使用 WQL 来创建有目标的查询,即做下列事情的查询:

    只返回托管资源所有实例的选定的属性。

    "SELECT DisplayName, State, StartMode FROM Win32_Service"
                

    返回一个类的选定的实例的所有属性。

    "SELECT * FROM Win32_Service WHERE State = 'Stopped'"
                

    返回一个类的选定实例的选定属性。

    "SELECT DisplayName,State,StartMode FROM Win32_Service WHERE State='Stopped'"
                

    创建有目标的查询有时会显著地提高数据返回的速度。(例如,只返回那些在应用程序事件日志中含有 EventCode 0 的事件要比返回所有事件日志中的所有事件快的多。)有目标的查询也让对返回的数据的工作变得更轻松。例如,假设您只想要应用程序事件日志中带有 EventCode 0 的事件,使用有目标的查询将只返回那些项目。相反,InstancesOf 将返回所有事件,而且您将不得不单独地检查每个事件并确定它是否:1. 来自应用程序事件日志并且,2. 带有 EventCode 0。虽然这可以完成,但是这太低效了而且对您来说需要额外的工作。

    有目标的查询还可以减少返回的数据的数量,对在网络上运行的脚本来说这是个重要的考虑。表 1 展示了一些不同查询类型的相关数字。如您所见,通过各种查询类型返回的数据的数量是有相当大的差别的。

    表 1. 比较不同的 WMI 实例检索方法和查询
    方法/WQL 查询 返回的字节

    objSWbemServices.InstancesOf("Win32_Service")

    157,398

    objSWbemServices.ExecQuery("SELECT * FROM Win32_Service")

    156,222

    objSWbemServices.ExecQuery("SELECT Name FROM Win32_Service")

    86,294

    objSWbemServices.ExecQuery("SELECT StartMode FROM Win32_Service")

    88,116

    objSWbemServices.ExecQuery("SELECT StartMode FROM Win32_Service WHERE State='Running'")

    52,546

    objSWbemServices.ExecQuery("SELECT StartMode, State FROM Win32_Service WHERE State='Running'")

    56,314

    objSWbemServices.ExecQuery("SELECT * FROM Win32_Service WHERE Name='WinMgmt'")

    27,852

    objSWbemServices.Get("Win32_Service.Name='WinMgmt'")

    14,860

    此时,我们希望我们已经说服了您,关于 ExecQuery 要比 InstancesOf 更好的问题。现在让我们从清单 2 转到一个通用的 WMI 脚本模板,它可以轻易地被修改以检索任何 WMI 托管资源的实例。清单 3 包含我们第一个模板。

    清单 3. 用于检索托管资源实例的模板

    strComputer = "."
    strNamespace = "\root\cimv2"
    strClass = "Win32_Service"
    Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & strNamespace)
    Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM " & strClass)
    For Each objSWbemObject In colSWbemObjectSet
    WScript.Echo "Display Name: " & objSWbemObject.DisplayName
    WScript.Echo "State:        " & objSWbemObject.State
    WScript.Echo "Start Mode:   " & objSWbemObject.StartMode
    Next
    

    要用其他 WMI 类使用这个模板:

    1.

    将 strClass 的值设置为目标托管资源的相应的 WMI 类。

    2.

    如必要,将 strNamespace 的值设置为目标类的 WMI 命名空间。

    3.

    替换显示属性及其值的 For Each 循环中的语句。删除下列行,并用在显示的属性值的相应的代码行替换它们。

    WScript.Echo "Display Name: " & objSWbemObject.DisplayName
                WScript.Echo "State:        " & objSWbemObject.State
                WScript.Echo "Start Mode:   " & objSWbemObject.StartMode
                

    Scripting Guys 免费放送如果您正在使用一个返回许多实例的托管资源(为了讨论的目的,我们将“许多”定义为超过 1000),您可以通过使用可选标记优化 ExecQuery 的行为。例如,假设您使用 ExecQuery 来查询事件日志记录(由 Win32_NTLogEvent 类建模)。如您已知的,事件日志会包含成千上万条记录。默认情况下,您可能会遇到与返回大量结果集相关的性能问题,比如事件日志查询。必须用这种方法来实现的原因是,WMI 为每个实例缓存了一个 SWbemObject 引用,或者在我们的例子中,是为每个事件日志记录。为了避免这个问题,您可以让 ExecQuery 来返回一个只进 SWbemObjectSet,如下所示。

    strComputer = "."
    strNamespace = "\root\cimv2"
    strClass = "Win32_NTLogEvent"
    Const wbemFlagReturnImmediately = &h10
    Const wbemFlagForwardOnly = &h20
    Set objSWbemServices = GetObject("winmgmts:\\" & strComputer & strNamespace)
    Set colSWbemObjectSet = objSWbemServices.ExecQuery("SELECT * FROM " & strClass, _
    "WQL" _
    wbemFlagReturnImmediately + wbemFlagForwardOnly)
    ' Insert remainder of script here (e.g., For Each Next loop)...
    

    wbemFlagReturnImmediately 标记(它是在我们前面简要说明的枚举之一中定义的)是默认的 ExecQuery 行为并且是半同步的。重要的优化是添加 wbemFlagForwardOnly 标记。将 wbemFlagReturnImmediatelywbemFlagForwardOnly 结合将获得一个只进的枚举数。只进的枚举数要比默认的枚举数执行快很多,因为 WMI 不维护对在 SWbemObjectSet 中对象的引用。

  • 相关阅读:
    Java基础语法与变量初步学习
    Java基本数据类型转换
    Java变量常量与基本数据类型
    Java进制转换
    Java 开发环境配置
    Java运算符
    STL—vector删除重复元素
    子窗口和父窗口重绘
    怎么判断文件是否被占用
    多线程的理解
  • 原文地址:https://www.cnblogs.com/ahuo/p/670853.html
Copyright © 2020-2023  润新知