Как завершить процессы от постоянного потребителя событий wmi - PullRequest
1 голос
/ 12 апреля 2011

Я пытаюсь создать постоянного потребителя событий wmi, который будет ожидать создания процесса с определенным параметром командной строки, а затем завершит его.

Пока что я могу заставить свой обработчик событий срабатывать, когда ожидается, и записывать в файл журнала тестирования. Я даже могу получить доступ к параметрам из события WMI с помощью TargetEvent.TargetInstance. Однако, когда я пытаюсь завершить вызов на нем, он терпит неудачу.

У меня также возникают проблемы при создании экземпляров таких объектов, как wscript.shell или wscript.network, которые не могут создать экземпляр. Я полагаю, что это может быть потому, что этот скрипт на самом деле не работает на хосте скриптов Windows.

Поэтому мой вопрос заключается в том, как мне заставить метод terminate работать с моим экземпляром Win32_Process или есть способ вызвать внешнюю команду (если я не могу использовать объект wscript.shell).

Здесь я получил большую часть информации о том, как создать мой файл mof: http://www.codeproject.com/KB/system/PermEvtSubscriptionMOF.aspx?display=Print

Мой файл настроек Mof выглядит следующим образом:

#pragma namespace("\\\\.\\root\\subscription")

instance of __EventFilter as $EventFilter
{
    Name  = "My Test Filter";
    EventNamespace = "Root\\Cimv2";
    Query = "Select * From __InstanceCreationEvent Within 2 " 
            "Where TargetInstance Isa \"Win32_Process\" "
            "And Targetinstance.Name = \"notepad.exe\" "
            "And Targetinstance.CommandLine LIKE \"%test.txt%\"";
    QueryLanguage = "WQL";
};

instance of ActiveScriptEventConsumer as $Consumer
{
    Name = "MyTestConsumer";
    ScriptingEngine = "VBScript";
    ScriptText = 
    "On Error Resume Next\n"
    "'Set WshShell = WScript.CreateObject(\"WScript.Shell\")\n"
    "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
    "Set objFile = objFSO.OpenTextFile(\"c:\\log.txt\", 8, True)\n"
    "objFile.WriteLine Time & \" \" & \" notepad started \" & TargetEvent.TargetInstance.Handle \n"    
    "objFile.Close\n"
    "TargetEvent.TargetInstance.Terminate()\n";

};

instance of __FilterToConsumerBinding
{
    Filter = $EventFilter;
    Consumer   = $Consumer;
};

Мой файл удаления mof:

#pragma namespace("\\\\.\\root\\subscription")
#Pragma deleteInstance("__EventFilter.Name=\"My Test Filter\"",FAIL)
#Pragma deleteInstance("ActiveScriptEventConsumer.Name=\"MyTestConsumer\"",FAIL)

#pragma deleteinstance ("__FilterToConsumerBinding.Consumer="
    "\"\\\\\\\\.\\\\root\\\\subscription:ActiveScriptEventConsumer.Name=\\\"MyTestConsumer\\\"\","
    "Filter=\"\\\\\\\\.\\\\root\\\\subscription:__EventFilter.Name=\\\"My Test Filter\\\"\"", FAIL)

1 Ответ

1 голос
/ 13 апреля 2011

Я понятия не имею, в чем причина этого, но мне так и не удалось заставить это работать. На первый взгляд это должно быть - TargetEvent.TargetInstance.Name возвращает имя процесса и т. Д. Но при вызове метода в wbemess.log записывается ошибка:

Обработчик сценариев сообщает: Ошибка времени выполнения Microsoft VBScript: объект не поддерживает это свойство или метод: 'TargetEvent.TargetInstance.Terminate' (Среда, 13 апреля, 19:44:54 2011.15735734): событие удаления, предназначенное для потребителя событий ActiveScriptEventConsumer = "TestConsumer" в пространстве имен //./root/subscription

Вот мой обходной путь:

instance of __EventFilter as $EventFilter
{
    EventNamespace = "Root\\Cimv2";
    Name  = "New Process Instance Filter";
    Query = "Select * From __InstanceCreationEvent Within 2" 
            "Where TargetInstance Isa \"Win32_Process\" "
            "And Targetinstance.Name = \"notepad.exe\" ";
    QueryLanguage = "WQL";
};

instance of ActiveScriptEventConsumer as $Consumer
{
    Name = "TargetEventConsumer";
    ScriptingEngine = "VBScript";
    ScriptText = 
    "Set objWmi = GetObject(\"winmgmts:\")\n"
    "\n"
    "Set objProcess = objWmi.Get(\"Win32_Process.Handle='\" _\n"
    "    & TargetEvent.TargetInstance.Handle & \"'\")\n"
    "\n"
    "objProcess.Terminate\n";
};

instance of __FilterToConsumerBinding
{
    Consumer   = $Consumer;
    Filter = $EventFilter;
};

В скрипте я использую SWbemServices.Get (), чтобы получить созданный экземпляр процесса, а затем Terminate works. Просто передайте TargetEvent.TargetInstance.Handle в SWbemServices.Get ().

Вам не удалось использовать объект WshShell, потому что вы пытались создать его с помощью WScript.CreateObject, а WScript недоступен движку ActiveScriptConsumer VBScript. Это должно работать, если вы используете вместо этого функцию CreateObject () VBScript. То же самое с WshNetwork.

...