I am trying to register a permanent WMI event on my machine, where if a file is created in the folder C:\test
, a script should run.
I have successfully managed to register similar events where the action is to log a line to a file, but for some reason when trying to execute a script I just get no response.
Here is the query I am using:
$query=@"
Select * from __InstanceCreationEvent within 10
where targetInstance isa 'Cim_DirectoryContainsFile'
and targetInstance.GroupComponent='Win32_Directory.Name="C:\\\\test"'
"@
I have tried registering the event in a few different ways with no success, and was hoping someone could help me understand where I am going wrong.
Take for example the following script:
$computer = $env:COMPUTERNAME
$filterNS = "root\cimv2"
$wmiNS = "root\subscription"
$query = @"
Select * from __InstanceCreationEvent within 1
where targetInstance isa 'Cim_DirectoryContainsFile'
and targetInstance.GroupComponent = 'Win32_Directory.Name="c:\\\\test"'
"@
$filterName = "NewFileFilter"
$scriptFileName = "C:\test\test.vbs"
$filterPath = Set-WmiInstance -Class __EventFilter `
-ComputerName $computer -Namespace $wmiNS -Arguments `
@{name=$filterName; EventNameSpace=$filterNS; QueryLanguage="WQL";
Query=$query}
$consumerPath = Set-WmiInstance -Class ActiveScriptEventConsumer `
-ComputerName $computer -Namespace $wmiNS `
-Arguments @{name="MyConsumer"; ScriptFileName=$scriptFileName;
ScriptingEngine="VBScript"}
Set-WmiInstance -Class __FilterToConsumerBinding -ComputerName $computer `
-Namespace $wmiNS -arguments @{Filter=$filterPath; Consumer=$consumerPath} |
out-null
Where test.vbs
is a one-liner: MsgBox("Hello!")
After running this, I can call the following:
Get-WmiObject -Namespace root\Subscription -Class __Eventfilter
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
And get the below output, which shows me that the event has indeed been registered:
__GENUS : 2
__CLASS : __EventFilter
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __EventFilter.Name="NewFileFilter"
__PROPERTY_COUNT : 6
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \\WIN7-IT3\ROOT\Subscription:__EventFilter.Name="NewFileFilter"
CreatorSID : {1, 5, 0, 0...}
EventAccess :
EventNamespace : root\cimv2
Name : NewFileFilter
Query : Select * from __InstanceCreationEvent within 1
where targetInstance isa 'Cim_DirectoryContainsFile'
and targetInstance.GroupComponent =
'Win32_Directory.Name="c:\\\\test"'
QueryLanguage : WQL
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : ActiveScriptEventConsumer
__SUPERCLASS : __EventConsumer
__DYNASTY : __SystemClass
__RELPATH : ActiveScriptEventConsumer.Name="MyConsumer"
__PROPERTY_COUNT : 8
__DERIVATION : {__EventConsumer, __IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \\WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="MyCon
sumer"
CreatorSID : {1, 5, 0, 0...}
KillTimeout : 0
MachineName :
MaximumQueueSize :
Name : MyConsumer
ScriptFilename : C:\test\test.vbs
ScriptingEngine : VBScript
ScriptText :
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : __FilterToConsumerBinding
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __FilterToConsumerBinding.Consumer="ActiveScriptEventConsum
er.Name=\"MyConsumer\"",Filter="__EventFilter.Name=\"NewFil
eFilter\""
__PROPERTY_COUNT : 7
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \\WIN7-IT3\ROOT\Subscription:__FilterToConsumerBinding.Cons
umer="ActiveScriptEventConsumer.Name=\"MyConsumer\"",Filter
="__EventFilter.Name=\"NewFileFilter\""
Consumer : ActiveScriptEventConsumer.Name="MyConsumer"
CreatorSID : {1, 5, 0, 0...}
DeliverSynchronously : False
DeliveryQoS :
Filter : __EventFilter.Name="NewFileFilter"
MaintainSecurityContext : False
SlowDownProviders : False
PSComputerName : WIN7-IT3
However, when I create a file in C:\test
, nothing happens. The most frustrating this about this, is that I can create a similar event which uses the LogFileEventConsumer
and this works perfectly (a line is logged to the specified file when a new file is added to C:\test
).
Does anyone know what is going on here, or how I can debug this effectively? I have not found any way to get the binding to somehow output errors or log any kind of details about what is going on, and have not been able to work out what CIM WMI Studio is meant to do (it doesn't seem to work at all for me).
Any help is much appreciated, and please let me know if I can post any more details like any other code I have tried or any logs - thanks.
I was able to achieve this using the following script :
$query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA "Cim_DirectoryContainsFile" AND TargetInstance.GroupComponent="Win32_Directory.Name='C:\\test'"
"@
#Set up hash table for splatting
$wmiParams = @{
Computername = $env:COMPUTERNAME
ErrorAction = 'Stop'
NameSpace = 'root\subscription'
}
# Filter
#Creating a new event filter
$wmiParams.Class = '__EventFilter'
$wmiParams.Arguments = @{
Name = 'WatchFiles'
EventNamespace = 'root\CIMV2'
QueryLanguage = 'WQL'
Query = $query
}
$filterResult = Set-WmiInstance @wmiParams
# Consumer
$wmiParams.Class = 'ActiveScriptEventConsumer'
$wmiParams.Arguments = @{
KillTimeout = 0
MachineName = $env:COMPUTERNAME
ScriptingEngine = 'VBScript'
ScriptText =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\Log.log", 8, True)
objFile.WriteLine "hellohellohellohellohellohello"
objFile.Close
"@
ScriptFileName = $null
Name = 'ActiveScriptEventConsumer'
}
$consumerResult = Set-WmiInstance @wmiParams
# Binding
$wmiParams.Class = '__FilterToConsumerBinding'
$wmiParams.Arguments = @{
Filter = $filterResult
Consumer = $consumerResult
}
$bindingResult = Set-WmiInstance @wmiParams
Notice the way I have formatted the $query
filter, and that the only character that needs escaping is the \
, due to the Here-String
(@""@
) I used.
Some more things to note from here :
When creating VBScript or JScript scripts to use with ActiveScriptEventCosumer, you need to be aware of some limitations:
•ActiveScriptEventConsumer doesn't use the Windows Script Host (WSH), which is widely used in system administration scripts. This means that you can not use the WScript object or any of its properties and methods (like WScript.CreateObject, WScript.Sleep etc.).
•The script can not generate any screen output, which means that you can not use the VBScript MsgBox function.
•The script does not have network access.
•The script can't use any user specific data, such as environment variables or network shares.
This could explain the above failure, as the script I was referring to contained a MsgBox()
, which cannot run in these circusmtances.