• WMI事件监控


    特定对象的属性发生改变时发出的通知,其中包括增加、修改、删除三种类型。

    首先看到下面一个例子:

    $strComputer = "."

    $objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")

    $strWQL = "SELECT * " & _
    "FROM __InstanceCreationEvent " & _
    "WITHin$2 " & _
    "WHERE TargetInstance ISA 'Win32_Process' " & _
    "AND TargetInstance.Name = 'notepad.exe'"

    ConsoleWrite( "Waiting for a new instance of Notepad to start..." & @CrLf )
    $objEventSource = $objWMIService.ExecNotificationQuery($strWQL)
    $objEventObject = $objEventSource.NextEvent()
    ConsoleWrite( "A new instance of Notepad was just started." & @CrLf )

    当你运行记事本时程序就会发出一条提示。下面是对这段代码的解释:

    $strComputer = "."

    $objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")

    连接到命名空间。

    $strWQL = "SELECT * " & _
    "FROM __InstanceCreationEvent " & _
    "WITHin 2 " & _
    "WHERE TargetInstance ISA 'Win32_Process' " & _
    "AND TargetInstance.Name = 'notepad.exe'"

    这是一段WQL查询代码,__InstanceCreationEvent 表示监视新实例的建立,在这里表示新进程建立。类似的东西还有__InstanceModificationEvent、__InstanceDeletionEvent、__InstanceOperationEvent,它们分别表示修改、删除、全部操作(既以上三种的综合)。WITHin 2 表示每两秒查询一次。TargetInstance ISA 'Win32_Process' 表示监控Win32_Process类。TargetInstance.Name = 'notepad.exe'表示监控Name属性为notepad.exe的实例。

    $objEventSource = $objWMIService.ExecNotificationQuery($strWQL)
    $objEventObject = $objEventSource.NextEvent()

    ExecNotificationQuery和ExecQuery的意义差不多一样,不过前者是专门用来获取WMI事件。$objEventSource.NextEvent() 表示不断进行WQL查询,直到通知产生,这段时间内脚本会暂停。

    另外,用$objEventObject.Path_.Class你可以获取通知的种类,比如__InstanceCreationEvent。你还可以用$objEventObject.TargetInstance.+属性 来获取产生通知的实例的属性。

    理论就讲到这里,剩下的东西相信大家看了下面的几个例子后就明白了。

    下面是一段监视进程的范例:

    $strComputer = "."

    $objWMIService = ObjGet("winmgmts://" & $strComputer & "/root/cimv2")

    $strQuery = "SELECT * " & _
    "FROM __InstanceOperationEvent " & _
    "WITHin 2 " & _
    "WHERE TargetInstance ISA 'Win32_Process' "

    $objEventSource = $objWMIService.ExecNotificationQuery($strQuery)

    ConsoleWrite( "进程监控开始..." & @CRLF )

    While 1
    $objEventObject = $objEventSource.NextEvent()
    Switch $objEventObject.Path_.Class
    Case "__InstanceCreationEvent"
    ConsoleWrite("新进程建立:" & $objEventObject.TargetInstance.Name & @CrLf )
    Case "__InstanceDeletionEvent"
    ConsoleWrite("进程被关闭:" & $objEventObject.TargetInstance.Name & @CrLf )
    EndSwitch
    WEnd

    下面是一段文件监控的例子:

    $strComputer = "."
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")

    $colMonitoredEvents = $objWMIService.ExecNotificationQuery _
    ("SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE " _
    & "Targetinstance ISA 'CIM_DirectoryContainsFile' and " _
    & "TargetInstance.GroupComponent= " _
    & "'Win32_Directory.Name=""c:\\\\1""'")

    While 1
    $objEventObject = $colMonitoredEvents.NextEvent()

    Select
    Case $objEventObject.Path_.Class()="__InstanceCreationEvent"
    ConsoleWrite ("A new file was just created: " & $objEventObject.TargetInstance.PartComponent() & @CR)
    Case $objEventObject.Path_.Class()="__InstanceDeletionEvent"
    ConsoleWrite ("A file was just deleted: " & $objEventObject.TargetInstance.PartComponent() & @CR)
    EndSelect
    WEnd

    下面是监控USB设备的例子:

    $strComputer = "."
    $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\cimv2")

    $colEvents = $objWMIService.ExecNotificationQuery _
    ("Select * From __InstanceOperationEvent Within 5 Where " _
    & "TargetInstance isa 'Win32_LogicalDisk'")

    While 1
    $objEvent = $colEvents.NextEvent
    If $objEvent.TargetInstance.DriveType = 2 Then
    Select
    Case $objEvent.Path_.Class()="__InstanceCreationEvent"
    Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been added." & @CR)
    Case $objEvent.Path_.Class()="__InstanceDeletionEvent"
    Consolewrite("Drive " & $objEvent.TargetInstance.DeviceId & "has been removed."& @CR)
    EndSelect
    EndIf
    WEnd

    #ifndef _WIN32_DCOM
    #define _WIN32_DCOM
    #endif

    #include <windows.h>
    #include <objbase.h>
    #include <atlbase.h>
    #include <iostream>
    #include <wbemidl.h>
    #include <comutil.h>
    #include <string.h>

    int main( int argc, char** argv )
    {
        HRESULT hr = CoInitializeEx( NULL, COINIT_MULTITHREADED );
        if ( FAILED( hr ) )
        {
            std::cerr << "COM initialization failed" << std::endl;
            return -1;
        }

        // setup process-wide security context
        hr = CoInitializeSecurity( NULL, // we're not a server
                                   -1// we're not a server
                                   NULL, // dito
                                   NULL, // reserved
                                   RPC_C_AUTHN_LEVEL_DEFAULT, // let DCOM decide
                                   RPC_C_IMP_LEVEL_IMPERSONATE,
                                   NULL,
                                   EOAC_NONE,
                                   NULL );
        if ( FAILED( hr ) )
        {
            std::cerr << "Security initialization failed" << std::endl;
            return -1;
        }

        int result = 0;
        // we're going to use CComPtr<>s, whose lifetime must end BEFORE CoUnitialize is called
        {
            // connect to WMI
            CComPtr< IWbemLocator > locator;
            hr = CoCreateInstance( CLSID_WbemAdministrativeLocator, NULL,
                                CLSCTX_INPROC_SERVER,
                                IID_IWbemLocator, reinterpret_cast< void** >( &locator ) );
            if ( FAILED( hr ) )
            {
                std::cerr << "Instantiation of IWbemLocator failed" << std::endl;
                return -1;
            }

            // connect to local service with current credentials
            CComPtr< IWbemServices > service;
            hr = locator->ConnectServer( L"root\\cimv2", NULL, NULL, NULL,
                                         WBEM_FLAG_CONNECT_USE_MAX_WAIT,
                                         NULL, NULL, &service );
            if ( SUCCEEDED( hr ) )
            {
                // execute a query
                CComPtr< IEnumWbemClassObject > enumerator;
                hr = service->ExecNotificationQuery( L"WQL", L"SELECT * FROM __InstanceOperationEvent WITHIN 5 WHERE ( TargetInstance ISA \'Win32_LogicalDisk\' ) ",
                                         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator );
                std::cout << "QUERY " << hr << std::endl;
                if ( SUCCEEDED( hr ) )
                {
    //#error "Comment out after read: program will terminate after two events; be sure not kill program by CTRL-C etc. See caveats section in article"
                    int count = 0;
                    do {
                        CComPtr< IWbemClassObject > folder = NULL;
                        ULONG retcnt = 0L;
                        while ( ( hr = enumerator->Next( WBEM_INFINITE, 1L, &folder, &retcnt ) ) == WBEM_S_TIMEDOUT );
                        if ( SUCCEEDED( hr ) && ( hr != WBEM_S_FALSE ) )
                        {
                            if ( retcnt > 0 )
                            {


                                _variant_t var_OP;
                                hr = folder->Get( L"__Class"0, &var_OP, NULL, NULL );

                                _bstr_t vlOP = var_OP;
                                //count ++;
                                
    // query returns a result - handle the event
                                _variant_t var_val;
                                hr = folder->Get( L"TargetInstance"0, &var_val, NULL, NULL );
                                if ( SUCCEEDED( hr ) )
                                {
                                    IUnknown* str = var_val;
                                    CComPtr< IWbemClassObject > obj;
                                    hr = str->QueryInterface( IID_IWbemClassObject, reinterpret_cast< void** >( &obj ) );
                                    if ( SUCCEEDED( hr ) )
                                    {
                                        _variant_t cn;
                                        hr = obj->Get( L"__Class"0, &cn, NULL, NULL );
                                        if ( SUCCEEDED( hr ) )
                                        {
                                            _bstr_t name = cn;
                                            if ( name == _bstr_t( L"Win32_LogicalDisk" ) )
                                            {
                                                _variant_t labl;
                                                obj->Get( L"Name"0, &labl, NULL, NULL );
                                                
                                                _bstr_t vl = labl;
                                                std::cout <<vlOP<< " Change to disk " << vl << std::endl;
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    std::cerr << "IWbemClassObject::Get failed" << std::endl;
                                    result = -1;
                                }
                                break;
                            }
                            else
                            {
                                std::cout << "Enumeration empty" << std::endl;
                            }
                        }
                        else if ( FAILED( hr ) )
                                {
                                    std::cerr << "Error in iterating through enumeration 0x" << std::hex << hr << std::dec << std::endl;
                                    result = -1;
                                } else std::cout << "empty" << std::endl;
                    } while ( count < 2 );
                }
                else
                {
                    std::cerr << "Query failed" << std::endl;
                    result = -1;
                }
            }
            else
            {
                std::cerr << "Couldn't connect to service" << std::endl;
                result = -1;
            }
        }
        CoUninitialize();

        return result;
    }
  • 相关阅读:
    [BJOI2019]排兵布阵
    关于DP题的状态定义转换和各种优化这档事
    容斥原理学习笔记
    莫比乌斯反演学习笔记
    每日进度
    每日进度
    每日进度
    每日进度
    每日进度
    每日进度
  • 原文地址:https://www.cnblogs.com/ahuo/p/2302078.html
Copyright © 2020-2023  润新知