Windows Management Instrumentation WMI Security Technology Learning

目录

0. 引言
1. WMI(Windows Management Instrumentation)简介
2. 基于WMI的攻击向量
3. WMI编程示例

0. 引言

在进行服务器主机的入侵检测、安全攻防的研究中,常常会涉及到大量的和windows操作系统功能、资源、设备相关的操作(例如通过WMI COM API关闭FTP匿名登录等),而WMI提供了一个对windows操作系统底层各种异构模块/资源的统一接口,通过研究WMI(Windows Management Instruction)技术可以更加深入地了解如果通过API方式操作windows系统的基础服务,通过WMI技术,我们可以实现

1. windows操作系统的配置加固
2. 当前系统的安装程序的列表探测,确定系统安装的反病毒软件

0x1: COM Component(COM组件)技术

因为WMI是架构在COM技术之上的,在开始学习WMI技术之前,我们先来学习一下windows中的COM Component组件技术

组件对象模型(Component Object Model COM),是微软的一套软件组件的二进制接口标准。这使得跨编程语言的进程间通信、动态对象创建成为可能。COM是多项微软技术与框架的基础,包括

1. OLE
2. OLE自动化
3. ActiveX
4. COM+
5. DCOM
6. Windows shell
7. DirectX
8. Windows Runtime
9. WMI
..

什么是COM组件

1. COM组件是以WIN32动态链接库(DLL)、或可执行文件(EXE)形式发布的可执行代码组成,但要注意的是,COM组件不是DLL,只是利用DLL来给组件提供动态链接的能力
2. COM组件是遵循COM规范编写的
3. COM组件是一些小的二进制可执行文件
4. COM组件可以给应用程序、操作系统以及其他组件提供服务
5. 自定义的COM组件可以在运行时刻同其他组件连接起来构成某个应用程序
6. COM组件可以动态的插入或卸出应用
7. COM组件必须是动态链接的
8. COM组件必须隐藏(封装)其内部实现细节
9. COM组件必须将其实现的语言隐藏
10. COM组件必须以二进制的形式发布
11. COM组件必须可以在不妨碍已有用户的情况下被升级
12. COM组件可以透明的在网络上被重新分配位置
13. COM组件按照一种标准的方式来宣布它们的存在

Relevant Link:

http://freebird.blog.51cto.com/372076/184567/
http://zh.wikipedia.org/wiki/%E7%BB%84%E4%BB%B6%E5%AF%B9%E8%B1%A1%E6%A8%A1%E5%9E%8B
http://baike.baidu.com/view/185316.htm
http://www.cppblog.com/3522021224/archive/2007/06/22/26803.html

1. WMI(Windows Management Instrumentation)简介

Windows Management Instrumentation是用于提供共同的界面和对象模式以便访问

1. 操作系统
2. 设备
3. 应用程序
4. 服务的管理信息

如果此服务被终止,多数基于 Windows 的软件将无法正常运行。如果此服务被禁用,任何依赖它的服务将无法启动,WMI是windows中的一个核心服务,它提供了一个标准的基础结构来监视和管理系统资源的服务

WMI是Microsoft实现的一个Web-Based Enterprise Management(WBEM)的执行方式,支持Distributed Management Task Force(DMTF),WMI提供您管理服务的能力

通过这张架构图,我们得到如下结论

1. WMI Providers And Managemed Object
这是整个WMI体系的最底层,它对所有的"提供者(Provider)"提供了封装和抽象,包括
    1.1 Native C/C++ Provider COM object 
    A WMI provider is a COM object that monitors one or more "managed objects" for WMI. A "managed object" is a logical or physical enterprise component, such as a hard disk drive,
network adapter, database system, operating system, process, or service.
1) SNMP WMI Provider: SNMP Managed Entity 2) Cimv2 WMI Provider: Windows(Win32) Managed Entity 3) Security Provider: Retrieves or changes security settings that control ownership, auditing, and access rights to files, directories, and shares .... 4) Any Managed Entity(Native Code) Similar to a driver, a provider supplies WMI with data from a managed object and handles messages from WMI to the managed object. WMI providers consist of a DLL file and a
Managed Object Format (MOF) file that defines the classes for which the provider returns data and performs operations. Providers, like WMI C++ applications, use the COM API for
WMI.
1.2 .NET C#、VB.NET、And so on COM Inter-Op 1) .NET Managed Application/Entity 2. WMI Infrastructure The WMI infrastructure is a Microsoft Windows operating system component 2.1 WMI Core(CIM Object Managedr) 2.2 WMI Repository WMI repository is organized by WMI namespaces,WMI的namespace由系统自身创建和Provider创建2部分组成,例如 1) rootdefault 2) rootcimv2 3) rootsubscription ... 由底层的Provider创建的namespace 4) /LM/MSFTPSVC/n .. The WMI service acts as an intermediary between the providers, management applications, and the WMI repository. Only static data about objects is stored in the repository,
such as the classes defined by providers. WMI obtains most data dynamically from the provider when a client requests it. You also can set up subscriptions to receive event
notifications from a provider 简单来说,WMI Repository就相当于一个保存WMI信息的数据库,而底层的Provider所提供的信息就相当于一个个独立的数据表,在WMI中称之为命名空间namespace,我们在进行WMI查询之前,需要明确指定需要查询的namespace 3. WMI Consumers(Management Applications) A WMI consumer is a management application or script that interacts with the WMI infrastructure. A management application can query, enumerate data, run provider methods, or
subscribe to events by calling either the "COM API" for WMI or the Scripting API for WMI. The only data or actions available for a managed object, such as a disk drive or a
service, are those that a provider supplies. 这一层是程序员能直接接触到的API层面的东西,我们可以使用C
++、WMI Script脚本编写代码去操作WMI COM API对WMI进行操作 3.1 C/C++ Client 3.2 Scripts 3.3 .NET Client Application
关于WMI COM API接口的相关信息,请参阅
http://msdn.microsoft.com/en-us/library/aa389276(v=vs.85).aspx

关于Scripting API for WMI接口的相关信息,请参阅(Scripting API For WMI本质上还是调用的COM API)
http://msdn.microsoft.com/en-us/library/aa393258(v=vs.85).aspx

0x1: WMI的功能

1. Windows管理规范(Windows Management Instrumentation)是一项核心的 Windows 管理技术
2. 用户可以使用 WMI 管理本地和远程计算机
3. WMI 通过编程和脚本语言为日常管理提供了一条连续一致的途径。例如,用户可以:
    1) 在远程计算机器上启动一个进程 
    2) 设定一个在特定日期和时间运行的进程 
    3) 远程启动计算机。
    4) 获得本地或远程计算机的已安装程序列表。
    5) 查询本地或远程计算机的 Windows 事件日志 

在使用WMI的时候,我们经常会涉及到的2个话题就是命名空间namespace、以及COM API接口

0x2: WMI的命令空间namespace

strComputer = "."
Call EnumNameSpaces("root")

Sub EnumNameSpaces(strNameSpace)
    WScript.Echo strNameSpace 
    Set objWMIService = GetObject("winmgmts:\" & strComputer & _
        "" & strNameSpace)
    Set colNameSpaces = objWMIService.InstancesOf("__NAMESPACE")
    For Each objNameSpace In colNameSpaces
        Call EnumNameSpaces(strNameSpace & "" & objNameSpace.Name)
    Next
End Sub

在命令行下输入指令

//如果不加CScript,就会以弹框的形式进行输出
CScript enumwmi.vbs

得到命令空间的枚举结果

Microsoft (R) Windows Script Host Version 5.8
版权所有(C) Microsoft Corporation 1996-2001。保留所有权利。

root
rootsubscription
rootsubscriptionms_804
rootsubscriptionms_409
rootDEFAULT
rootDEFAULTms_804
rootDEFAULTms_409
rootCIMV2
rootCIMV2Security
rootCIMV2SecurityMicrosoftTpm
rootCIMV2SecurityMicrosoftVolumeEncryption
rootCIMV2ms_804
rootCIMV2power
rootCIMV2powerms_804
rootCIMV2powerms_409
rootCIMV2ms_409
rootCIMV2TerminalServices
rootCIMV2TerminalServicesms_804
rootCIMV2TerminalServicesms_409
rootCIMV2Applications
rootCIMV2ApplicationsWindowsParentalControls
rootCIMV2ApplicationsGames
rootCIMV2ApplicationsGamesms_804
rootCIMV2ApplicationsGamesms_409
rootCli
rootCliMS_804
rootCliMS_409
root
ap
rootMicrosoftIISv2
rootMicrosoftIISv2MS_804
rootSECURITY
rootSecurityCenter2
rootRSOP
rootRSOPUser
rootRSOPUserS_1_5_21_911831770_3020607629_1626131430_1001
rootRSOPUserS_1_5_21_1831597161_2851159394_2615556374_500
rootRSOPUserS_1_5_21_1650095739_3452460257_125639005_500
rootRSOPUserS_1_5_21_3111613574_2524581245_2586426736_500
rootRSOPUserS_1_5_21_3727386885_3056668215_3391246470_197649
rootRSOPUserS_1_5_21_2209633111_3508286175_922290665_500
rootRSOPUserS_1_5_21_1991281308_1550804765_3468072676_1000
rootRSOPUserms_804
rootRSOPUserS_1_5_21_1991281308_1550804765_3468072676_500
rootRSOPUserS_1_5_21_911831770_3020607629_1626131430_500
rootRSOPUserms_409
rootRSOPUserS_1_5_21_3952311282_3270686217_2811382985_500
rootRSOPComputer
rootRSOPComputerms_804
rootRSOPComputerms_409
rootWebAdministration
rootWebAdministrationMS_804
rootWMI
rootWMIMS_804
rootWMIms_409
rootdirectory
rootdirectoryLDAP
rootdirectoryLDAPms_804
rootdirectoryLDAPms_409
rootPolicy
rootPolicyms_804
rootPolicyms_409
rootInterop
rootInteropms_804
rootInteropms_409
rootServiceModel
rootSecurityCenter
rootMicrosoft
rootMicrosoftSqlServer
rootMicrosoftSqlServerServerEvents
rootMicrosoftSqlServerServerEventsSQLEXPRESS
rootMicrosoftSqlServerComputerManagement10
rootMicrosoftSqlServerComputerManagement10ms_804
rootMicrosoftHomeNet
rootaspnet

连接到指定的WMI命名空间namespace之后,就可以借助相应的COM API对namespace中存储的信息进行读写了,这里要特别注意的是

WMI namespace是一个层次树tree结构,每一层的Class都有自己对应的成员属性properties,我们在获取信息的时候,需要明白自己需要获取的信息位于Class Tree的哪一层,这有点类似java中的jar包,每一层都不断嵌套,同时每一层又都有自己的独有的东西,不能递归包含

http://www.wutils.com/wmi/classes/IIsFtpServerSetting.html

0x3: WMI COM API接口

You can use the WMI Component Object Model (COM) API to write management client applications or create a new WMI provider. The COM API reference provides information for advanced system administrators, as well as developers who are writing client and provider applications.

1. IEnumWbemClassObject    
Enumerator that works with objects of type IWbemClassObject. It is similar to standard COM enumerators, such as IEnumVariant.

2. IMofCompiler    
Implemented by Mofd.dll, this interface provides a COM interface that is used by the MOF compiler and any other applications that compile MOF files.

3. IUnsecuredApartment    
Used to simplify the process of making asynchronous calls from a client process.

4. IWbemBackupRestore    
Backs up and restores the contents of the WMI repository.

5. IWbemCallResult
Used for semisynchronous calls of the IWbemServices interface. When making such calls, the called IWbemServices method returns immediately, along with an IWbemCallResult object.

6. IWbemCausalityAnalysis    
Tracks child requests that are generated from a parent request.

7. IWbemClassObject    
Contains and manipulates both class definitions and class object instances. Developers need not implement this interface; WMI provides its implementation.

8. IWbemConfigureRefresher    
Used by client code to add or remove enumerators, objects, and nested refreshers into a refresher.

9. IWbemContext    
Optionally used to communicate additional context information to providers when submitting IWbemServices calls to Windows Management.

10. IWbemDecoupledBasicEventProvider    
Registers decoupled providers with WMI.

11. IWbemDecoupledRegistrar    
Associates decoupled providers with WMI. This interface allows a process-hosted provider to define the interoperability lifetime of the interface and coexist with other providers.

12. IWbemEventConsumerProvider    
Provides the primary interface for an event consumer provider. Through this interface and the FindConsumer method, an event consumer provider can indicate which event consumers should receive a given event.

13. IWbemEventProvider    
Used to initiate communication with an event provider.

14. IWbemEventProviderQuerySink
Optionally implemented by event providers who want to know what kinds of event query filters are currently active to optimize performance.

15. IWbemEventProviderSecurity    
Optionally implemented by event providers who want to restrict consumer access to their event.

16. IWbemEventSink    
Initiates communication with an event provider using a restricted set of queries. This interface extends IWbemObjectSink, providing new methods dealing with security and performance.

17. IWbemHiPerfProvider    
Enables providers to supply refreshable objects and enumerators.

18. IWbemHiPerfEnum    
Used in refresher operations to provide rapid access to enumerations of instance objects.

19. IWbemLocator
Obtains the initial namespace pointer to the IWbemServices interface for WMI on a specific host computer.

20. IWbemObjectAccess    
Provides access to the methods and properties of an object. An IWbemObjectAccess object is a container for an instance updated by a refresher.

21. IWbemObjectSink    
Used to receive both the results of IWbemServices and certain types of event notifications.

22. IWbemObjectTextSrc    
Used to translate IWbemClassObject instances to and from differing text formats.

23. IWbemPropertyProvider
Supports retrieving and updating individual properties in an instance of a WMI class.

24. IWbemProviderIdentity    
Implemented by an event provider if the provider registers itself using more than one Name (multiple instances of __Win32Provider) with the same CLSID value. The class provides a mechanism for distinguishing which named provider should be used.

25. IWbemProviderInit    
Used to initialize providers.

26. IWbemProviderInitSink
Implemented by WMI and called by providers to report initialization status.

27. IWbemQualifierSet    
Acts as a container for the entire set of named qualifiers for a single property or entire object (a class or instance).

28. IWbemQuery    
Provides an entry point through which a WMI Query Language (WQL) query can be parsed.

29. IWbemRefresher    
Provides an entry point through which refreshable objects such as enumerators or refresher objects, can be refreshed.

30. IWbemServices    
Used by clients and providers to access WMI services. The interface is implemented only by WMI and is the primary WMI interface.

31. IWbemStatusCodeText    
Extracts text string descriptions of error codes or the name of the subsystem where the error occurred.

32. IWbemUnboundObjectSink    
Implemented by all logical event consumers. It is a simple sink interface that accepts delivery of event objects.

Relevant Link:

http://blog.csdn.net/wzsy/article/details/1632792
http://msdn.microsoft.com/zh-cn/library/aa394553(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/aa394570(v=vs.85).aspx
http://msdn.microsoft.com/zh-cn/library/aa393964(v=vs.85).aspx
http://msdn.microsoft.com/zh-cn/library/aa394582(v=vs.85).aspx
http://blog.itpub.net/7868752/viewspace-1056801/

2. 基于WMI的攻击向量

WMI(Windows管理规范)作为一项Windows管理技术,方便用户对计算机进行远程管理。但是它的易用性也导致了系统的安全性大幅下降。让用户的电脑除了自己账号密码的保护外再没有什么安全保护措施

我们接下来一起学习一下黑客是如何通过WMI技术对操作系统进行攻击的

0x1: 漏洞风险的起因

从WMI本质的功能看,它是为了让计算机的管理更容易,同时方便管理员远程操作系统而产生的,一般情况下,在本地计算机上执行的WMI操作也可以在远程计算机上执行,只要用户拥有该计算机的管理员权限
如果用户对远程计算机拥有权限并且远程计算机支持远程访问,那么用户就可以连接到该远程计算机并执行拥有相应权限的操作

因此,WMI能够成为远程控制下的一个"合法通道",有了这个通道,入侵者不需要对自己进行伪装,不必再为探测出对方账号的密码为空后,找不到连接对方系统的通道而发愁。
从安全攻防的角度来看,这就是一个典型的接口安全问题,一个原本是正常提供功能的接口因为没有进行必要的访问权限、使用权限的控制而导致"接口滥用",从而给了黑客可乘之机

0x2: 黑客可能采用的攻击方式

前面介绍了WMI的原理,下面我们实际了解下,如何通过WMI进行入侵,我们知道WMI是windows操作系统中的一个比较基础的服务,默认情况下操作系统都会开启这个服务端口的,即这条"WMI入侵通道"相对来说是比较畅通的,对黑客来说,它所需要的就是通过其他的途径获得一个可以登录系统的帐号、密码

1. 扫描135端口
要寻找可以通过WMI入侵的远程计算机,只要对135端口进行扫描就可以了。因为WMI服务默认打开的就是135端口。例如可以采用NTscan扫描工具,因为它不但可以对IPC$、SMB、WMI这些信息进行扫描,同时还可以对扫描到的远程账户
进行弱口令猜测,功能相对来说比较强大。
2. 运行NTscan,在程序窗口的"配置"区域中进行设置。首先在"起始IP""结束"选项中输入扫描的IP地址范围,接着选择"WMI扫描"选项,并且在"扫描打开端口的主机"选项后输入"135",最后点击"开始"按钮就开始进行扫描 3. 开启终端服务 找到可以入侵的远程计算机以后,就可以开始入侵操作了。首先是开启终端服务(Terminal Service) 要注意的是,通过WMI通道执行系统指令需要我们提供一对可能登录系统的帐号密码(这是这种攻击姿势的关键)

0x3: 如何防御WMI入侵

我们知道,攻防是一种针锋相对的技术,通过研究黑客在攻击时所采用的攻击向量的关键点,在这个关键点上进行过滤、或者阻断从而达到防御的目的

1. 屏闭135端口防御入侵
从WMI入侵的过程中我们可以看出,整个过程中使用的端口都是135。所以为了防止别人通过WMI进行入侵,我们可以使用防火墙对135端口进行屏蔽,这样就可以达到防范类似的入侵。用户加强自己的账号密码强度,也可以有效防范入侵

2. 加强帐号安全管理
从本质上讲,WMI是一个正常的功能通道,WMI本身并不是漏洞,产生漏洞的是系统帐号的泄漏,导致黑客滥用这个通道进行高危指令的执行,所以,我们可以从问题的源头入手,部署高强度密码策略,定期更换密码等措施解决问题

Relevant Link:

http://blog.itpub.net/7868752/viewspace-1056801/

3. WMI编程示例

操作WMI的方式有以下几种方式

1. Scripts written in Microsoft ActiveX script hosting, including Visual Basic Scripting Edition (VBScript) and Perl
2. Windows PowerShell
3. Visual Basic applications
4. Active Server Pages
5. C++ applications
6. .NET Framework applications written in C#, Visual Basic .NET, or J#

不论采用哪种方式,对WMI的操作都必须完成以下几个基本步骤

1. Obtaining Data from WMI:从WMI获取数据
    1) Decide which language to use
    2) Ensure that your connections to remote computers work
    3) Connecting to WMI on remote computers requires the correct security settings
    4) After connecting to WMI, you can obtain data through queries and enumerations.
    5) Registry data is available through WMI and you can create new keys and values or modify existing ones
    6) You can subscribe to event notifications through WMI, either temporarily between system reboots or permanently.
    7) Performance counter data for a system is available through WMI.

2. Providing Data to WMI
Decide on the type of provider to write. you can take several other approaches to writing a WMI COM provider:
    1) Using the WMI ATL Wizard in Visual Studio.
    2) Using COM directly in any integrated development environment.
    3) Using WMI in the .NET Framework to create a managed code provider.
    4) Using the provider framework classes is not recommended.

3. Important Tasks for WMI
    1) WMI Tasks for Scripts and Applications
    2) Creating a WMI Application or Script
    3) Connecting to WMI on a Remote Computer
    4) Connecting to WMI on a Remote Computer by Using Windows PowerShell
    5) Monitoring Events
    6) Providing Data to WMI
    7) Getting and Providing Data on a 64-bit Computer

这里我们以最常用的C++、VBS Scripts方式进行编程学习

0x1: C++ applications

// wmi_getsysinfo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <iostream>
#include <comdef.h>
#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib")

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    HRESULT hres;

    /*
    Initialize COM.
    由于用C++编写WMI应用是基于COM技术的,所以必须初始化COM库 
    */
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. " 
            << "Error code = 0x" 
            << hex << hres << endl;
        return 1;              // Program has failed.
    }

    /*
    Initialize
    初始化COM库安全级别
    */
    hres =  CoInitializeSecurity(
        NULL,     
        -1,      // COM negotiates service                  
        NULL,    // Authentication services
        NULL,    // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,    // authentication
        RPC_C_IMP_LEVEL_IMPERSONATE,  // Impersonation
        NULL,             // Authentication info 
        EOAC_NONE,        // Additional capabilities
        NULL              // Reserved
        );
    if (FAILED(hres))
    {
        cout << "Failed to initialize security. " 
            << "Error code = 0x" 
            << hex << hres << endl;
        CoUninitialize();
        return 1;          // Program has failed.
    }

    // Obtain the initial locator to Windows Management
    // on a particular host computer.
    IWbemLocator *pLoc = 0;
    /*
    连接到WMI命名空间
    通过调用CoCreateInstance初始化WMI的定位器(IWbemLocator类型的实例)
    */
    hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object. "
            << "Error code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;       // Program has failed.
    }

    IWbemServices *pSvc = 0;

    // Connect to the rootcimv2 namespace with the
    // current user and obtain pointer pSvc
    // to make IWbemServices calls.
    /*
    调用IWbemLocator::ConnectServer方法,通过这个定位器连接到WMI的命名空间,通过把一个IWbemServices的实例以参数形式传递给ConnectServer方法,就会创建这个服务。如我们需要一些BIOS信息,那么需要使用的WMI提供程序是Win32_BIOS,则需要连接到ROOT//CIMV2命名空间中。
    */
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\CIMV2"), // WMI namespace
        NULL,                    // User name
        NULL,                    // User password
        0,                       // Locale
        NULL,                    // Security flags                 
        0,                       // Authority       
        0,                       // Context object
        &pSvc                    // IWbemServices proxy
        );                            
    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" 
            << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return 1;                // Program has failed.
    }

    cout << "Connected to ROOT\CIMV2 WMI namespace" << endl;

    // Set the IWbemServices proxy so that impersonation
    // of the user (client) occurs.
    /*
    设置WMI服务的安全级别
    根据上一步得到的服务,设置相应的服务安全级别。通常来说,如果我们没有设置适当的安全属性,COM安全方案不允许一个进程去访问另一个进程,因此如果我们要访问一个外部进程的对象,那么我们应该设置适当的IWbemServices的安全级别。
    */
    hres = CoSetProxyBlanket(

        pSvc,                         // the proxy to set
        RPC_C_AUTHN_WINNT,            // authentication service
        RPC_C_AUTHZ_NONE,             // authorization service
        NULL,                         // Server principal name
        RPC_C_AUTHN_LEVEL_CALL,       // authentication level
        RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
        NULL,                         // client identity 
        EOAC_NONE                     // proxy capabilities     
        );
    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
    }

    //通过WQL使用WMI服务
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t("SELECT * FROM Win32_OperatingSystem"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);

    if (FAILED(hres))
    {
        cout << "Query for processes failed. "
            << "Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
    }
    else
    { 
        IWbemClassObject *pclsObj;
        ULONG uReturn = 0;

        while (pEnumerator)
        {
            hres = pEnumerator->Next(WBEM_INFINITE, 1, 
                &pclsObj, &uReturn);

            if(0 == uReturn)
            {
                break;
            }

            VARIANT vtProp;

            // Get the value of the Name property
            hres = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
            wcout << "Manufacturer Name : " << vtProp.bstrVal << endl;
            VariantClear(&vtProp);
        }

    }

    // Cleanup
    // ========

    pSvc->Release();
    pLoc->Release();     
    CoUninitialize(); 

    return 0;
}

0x2: Scripts written in Microsoft ActiveX script hosting

' Check command line parameters
Select Case WScript.Arguments.Count
    Case 0
        ' Default if none specified is local computer (".")
        Set objWMIService = GetObject( "winmgmts://./root/cimv2" )
        Set colItems = objWMIService.ExecQuery( "Select * from Win32_ComputerSystem", , 48 )
        For Each objItem in colItems
            strComputer = objItem.Name
        Next
    Case 1
        ' Command line parameter can either be a computer name
        ' or "/?" to request online help
        strComputer = Wscript.Arguments(0)
        if InStr( strComputer, "?" ) > 0 Then Syntax
    Case Else
        ' Maximum is 1 command line parameter
        Syntax
End Select

On Error Resume Next
' Connect to computer's WMI service
Set objWMIService = GetObject( "winmgmts://" & strComputer & "/root/cimv2" )
' Display error number and description if applicable
If Err.Number Then ShowError()

' Collect BIOS information
Set colItems = objWMIService.ExecQuery( "Select * from Win32_BIOS where PrimaryBIOS = true", , 48 )
' Display error number and description if applicable
If Err.Number Then ShowError()

' Initialize screen output variable
strMsg = vbCrLf & "BIOS summary for " & strComputer & ":" & vbCrLf

' Prepare collected info for display
For Each objItem in colItems
    strMsg = strMsg _
           & "    BIOS Name       :  " & objItem.Name & vbCrLf _
           & "    Version         :  " & objItem.Version & vbCrLf _
           & "    Manufacturer    :  " & objItem.Manufacturer & vbCrLf _
           & "    SMBIOS Version  :  " & objItem.SMBIOSBIOSVersion & vbCrLf
Next

' Display the results
WScript.Echo strMsg

' Done
WScript.Quit(0)


Sub ShowError
    strMsg = vbCrLf & "Error # " & Err.Number & vbCrLf & _
             Err.Description & vbCrLf & vbCrLf
    Syntax
End Sub


Sub Syntax
    strMsg = strMsg & vbCrLf & "BIOS.vbs,  Version 1.00" & vbCrLf & _
             "Display BIOS information." & vbCrLf & vbCrLf & _
             "Usage:  CSCRIPT  BIOS.VBS  [ computer_name ]" & _
             vbCrLf & vbCrLf & _
             "Where:  " & Chr(34) & "computer_name" & Chr(34) & _
             " is the name of a WMI enabled computer on the network" & _
             vbCrLf & vbCrLf & _
             "Written by Rob van der Woude" & vbCrLf & _
             "http://www.robvanderwoude.com" & vbCrLf & vbCrLf & _
             "Created using Microsoft's Scriptomatic tool" & vbCrLf & _
             "http://www.microsoft.com/technet/treeview/default.asp?" & _
             "url=/technet/scriptcenter/WMImatic.asp" & vbCrLf
    WScript.Echo strMsg
    ' Abort with return code 1
    WScript.Quit(1)
End Sub

Relevant Link:

http://msdn.microsoft.com/en-us/library/aa390418(v=vs.85).aspx
http://www.robvanderwoude.com/wmiexamples.php
http://www.codeproject.com/Articles/46390/WMI-Query-Language-by-Example

Copyright (c) 2014 LittleHann All rights reserved

原文地址:https://www.cnblogs.com/LittleHann/p/4022669.html