Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WMI Event Subscription and PowerShell execution

I need to launch a PowerShell script when a certain event happens, and I am using WMI classes to get persistence. I can get it working only partially, and need some help to make it fully working. So, here is what works and what doesn't...

The following code works, and will launch PowerShell in background when calc.exe is launched (I selected this event for simplicity just for testing purposes).

$fname = "testFilter"
$cname="testConsumer"
$exePath="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$query="SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='calc.exe'"
$WMIEventFilter=Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{Name=$fname;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$query}
$WMIEventConsumer=Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=$cname;ExecutablePath=$exePath}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer} | out-null

However, if I modify the $exePath variable to pass arguments to powershell.exe then it doesn't work anymore (no powershell process gets created).

I also tried to replace CommandLineEventConsumer with ActiveScriptEventConsumer, and use a VBScript to launch powershell. Here is the modified code (only line 3 and 5 are different):

$fname = "testFilter"
$cname="testConsumer"
$scriptPath="D:\Work\LaunchPowerShell.vbs"
$query="SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='calc.exe'"
$WMIEventFilter=Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{Name=$fname;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$query}
$WMIEventConsumer=Set-WmiInstance -Class ActiveScriptEventConsumer -Namespace "root\subscription" -Arguments @{Name=$cname;ScriptFileName=$scriptPath;ScriptingEngine="VBScript"}
Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer} | out-null

And the LaunchPowerShell.vbs:

Dim objShell : Set objShell = WScript.CreateObject("WScript.shell")
objShell.run("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe D:\Work\MyScript.ps1")

The VB script works as intended when launched from a command prompt (cmd.exe), but no luck to get powershell running when the event is being triggered (that is, when calc.exe is launched). It won't run even if I remove my script from the powershell arguments, so not sure what the problem is.

If anyone can help that would be much appreciated. Thanks!!!

like image 325
Eduard Turcan Avatar asked Feb 28 '26 15:02

Eduard Turcan


1 Answers

If you specify the CommandLineTemplate instead of the ExecutablePath you can add arguments to your string.

$fname = "testFilter"
$cname = "testConsumer"
$CommandLineTemplate = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -File D:\Work\MyScript.ps1"
$ExecutablePath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name='calc.exe'"

$WMIEventFilter = Set-WmiInstance -Class __EventFilter -Namespace "root\subscription" -Arguments @{Name=$fname;EventNameSpace="root\cimv2";QueryLanguage="WQL";Query=$query}
$WMIEventConsumer = Set-WmiInstance -Class CommandLineEventConsumer -Namespace "root\subscription" -Arguments @{Name=$cname;CommandLineTemplate=$CommandLineTemplate;ExecutablePath=$ExecutablePath }

Set-WmiInstance -Class __FilterToConsumerBinding -Namespace "root\subscription" -Arguments @{Filter=$WMIEventFilter;Consumer=$WMIEventConsumer} | out-null

Source:

CommandLineTemplate

Data type: string

Access type: Read-only

Standard string template that specifies the process to be started. This property can be NULL, and the ExecutablePath property is used as the command line.

like image 148
Shawn Esterman Avatar answered Mar 02 '26 13:03

Shawn Esterman