1 (изменено: neitan, 2010-08-25 17:58:13)

Тема: VBS: Терминирование процессов Win32_Process Terminate()(решено)

Всем доброго времени суток! Проблема пустяковая но изучать wmi я начал только несколько дней назад так что заранее извиняюсь за неграмотность:)
Данный скрипт должен отслеживать и завершать все новые процессы cmd.exe. Если процесс запущен под пользователем от которого запущен скрипт проблем нет, но если скрипт запускать под другим пользователем(Администратор) то "Terminate" возвращает 0, но процесс не завершает. На http://msdn.microsoft.com/en-us/library/aa393907 нашел что необходимо сделать чтобы завершить процесс другого пользователя:

To terminate a process that you do not own, enable the SeDebugPrivilege privilege. In VBScript, you can enable this privilege with the following lines of code:
Copy

Set objLoc = createobject("wbemscripting.swbemlocator")
objLoc.Security_.privileges.addasstring "sedebugprivilege", true

Но как это применить не понял.

strComputer = "."
Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE (TargetInstance ISA 'Win32_Process')")
Do While(True)
    Set objReceivedEvent = objEvents.NextEvent
    For Each objItem In objWMIService.ExecQuery("SELECT * FROM Win32_Process")
    If objItem.name = "cmd.exe" Then
    objItem.Terminate
    End If
    Next
Loop

2 (изменено: neitan, 2010-08-25 17:57:56)

Re: VBS: Терминирование процессов Win32_Process Terminate()(решено)

Задачу решил, надо было быть чуть-чуть внимательнее

strComputer = "."
Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE (TargetInstance ISA 'Win32_Process')")
Do While(True)
    Set objReceivedEvent = objEvents.NextEvent
    objWMIService.Security_.privileges.addasstring "sedebugprivilege", true
    For Each objItem In objWMIService.ExecQuery("SELECT * FROM Win32_Process")
    If objItem.name = "cmd.exe" Then
    objItem.Terminate
    End If
    Next
Loop

3 (изменено: Dmitrii, 2010-08-26 09:39:12)

Re: VBS: Терминирование процессов Win32_Process Terminate()(решено)

По-моему, так рациональнее:

strComputer = "."
Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
objWMIService.Security_.privileges.addasstring "sedebugprivilege", true
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")
Do
    Set objReceivedEvent = objEvents.NextEvent
    If StrComp(objReceivedEvent.TargetInstance.Name, "cmd.exe", vbTextCompare) = 0 Then objReceivedEvent.TargetInstance.Terminate
Loop

4

Re: VBS: Терминирование процессов Win32_Process Terminate()(решено)

Почему такие хорошие решения проблем, не идут в разделе Windows Script Host (VBScript, JScript, HTA)

5 (изменено: Dmitrii, 2010-08-26 21:17:31)

Re: VBS: Терминирование процессов Win32_Process Terminate()(решено)

armenxxx1 пишет:

Почему такие хорошие решения проблем, не идут в разделе Windows Script Host (VBScript, JScript, HTA)

Если речь о коллекции, то в ней уже есть примеры создания подписок на системные события, причём и синхронного (как в данном случае), и асинхронного типов. По-моему, нет только варианта для подписки полусинхронного типа.

Попутно сделаю ещё пару замечаний по обсуждаемому сценарию.
1. Добавить нужную привилегию можно непосредственно в операторе подключения к WMI-пространству.
То есть пару вырыжений

Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
objWMIService.Security_.Privileges.AddAsString "SeDebugPrivilege", True

можно заменить на одно

Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate,(Debug)}!\\.\root\CIMV2")

2. Имя контролируемого процесса можно задать непосредственно в операторе создания подписки.
То есть выражение

Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")

можно немного усложнить

Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='cmd.exe'")

В итоге получим такой вариант сценария:

strComputer = "."
Set objWMIService = Getobject("winmgmts:{impersonationLevel=impersonate,(Debug)}!\\.\root\CIMV2")
Set objEvents = objWMIService.ExecNotificationQuery("SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='cmd.exe'")
Do
    Set objReceivedEvent = objEvents.NextEvent
    objReceivedEvent.TargetInstance.Terminate
Loop