如何订阅 Windows 文件修改事件
How to Subscribe to Windows File Modification Events
我正在尝试通过此查询使用 WQL
订阅修改特定文件的事件:
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA "CIM_DataFile" AND TargetInstance.Drive="C:" AND TargetInstace.Path="\test\filewatching\"
我可以成功注册事件(见底部的输出)并且可以看到它与我注册的脚本(消费者)绑定。
但是,当我修改 C:\test\filewatching\
中的文件时,脚本不会 运行。
这是在同一文件夹中注册文件创建事件的代码,并且有效:
#WQL
$query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA "Cim_DirectoryContainsFile" AND TargetInstance.GroupComponent="Win32_Directory.Name='C:\test\filewatching'"
"@
$instanceFilter = ([WMICLASS]"\$Computername\root\subscription:__EventFilter").CreateInstance()
$instanceFilter.QueryLanguage = 'WQL'
$instanceFilter.Query = $query
$instanceFilter.Name = 'EventFilterNameHere'
$instanceFilter.EventNameSpace = 'root/CIMV2'
$result = $instanceFilter.Put()
# Consumer
$script =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
"@
$instanceConsumer = ([wmiclass]"\$Computername\root\subscription:ActiveScriptEventConsumer").CreateInstance()
$instanceConsumer.Name = 'ConsumerNameHere'
$instanceConsumer.ScriptingEngine = 'VBScript'
$instanceConsumer.ScriptFilename = ''
$instanceConsumer.ScriptText = $script
$instanceConsumer.Put()
# Binding
[object]$Filter = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventFilter | Sort Name)
[object]$Consumer = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventConsumer | Sort Name)
$instanceBinding = ([wmiclass]"\$Computername\root\subscription:__FilterToConsumerBinding").CreateInstance()
$instanceBinding.Filter = $Filter
$instanceBinding.Consumer = $Consumer
$instanceBinding.Put()
所以我知道我的 PowerShell 没有问题。这让我觉得我的查询一定是错误的。
我已经尝试对上述 InstanceModificationEvent
查询进行一些调整,但没有成功。 (这些调整包括将 C:
更改为 C
或从 TargetInstace.Path
中删除 \
等内容)。
我需要此订阅是永久的,并且如果 PC 打开或关闭则无法重置 - 这就是我使用 WQL 的原因。如果有人可以建议另一种实现相同目标的方法或如何解决我的查询,我将永远感激不已!
运行脚本后的输出:
Path : \WIN7-IT3\root\subscription:ActiveScriptEventConsumer.Name="Co
nsumerNameHere"
RelativePath : ActiveScriptEventConsumer.Name="ConsumerNameHere"
Server : WIN7-IT3
NamespacePath : root\subscription
ClassName : ActiveScriptEventConsumer
IsClass : False
IsInstance : True
IsSingleton : False
Path : \WIN7-IT3\root\subscription:__FilterToConsumerBinding.Consumer
="\\WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Na
me=\"ConsumerNameHere\"",Filter="\\WIN7-IT3\ROOT\Subscripti
on:__EventFilter.Name=\"EventFilterNameHere\""
RelativePath : __FilterToConsumerBinding.Consumer="\\WIN7-IT3\ROOT\Subscri
ption:ActiveScriptEventConsumer.Name=\"ConsumerNameHere\"",Filt
er="\\WIN7-IT3\ROOT\Subscription:__EventFilter.Name=\"Event
FilterNameHere\""
Server : WIN7-IT3
NamespacePath : root\subscription
ClassName : __FilterToConsumerBinding
IsClass : False
IsInstance : True
IsSingleton : False
正在查询 WMI 订阅:
Get-WmiObject -Namespace root\Subscription -Class __Eventfilter
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
Get-WMIObject -Namespace root\Subscription -Class ActiveScriptEventConsumer
查询后输出:
__GENUS : 2
__CLASS : __EventFilter
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __EventFilter.Name="EventFilterNameHere"
__PROPERTY_COUNT : 6
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:__EventFilter.Name="EventFilterNameHere"
CreatorSID : {1, 5, 0, 0...}
EventAccess :
EventNamespace : root/CIMV2
Name : EventFilterNameHere
Query : SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA
"CIM_DataFile" AND TargetInstance.Drive="C:" AND
TargetInstace.Path="\test\filewatching\"
QueryLanguage : WQL
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : ActiveScriptEventConsumer
__SUPERCLASS : __EventConsumer
__DYNASTY : __SystemClass
__RELPATH : ActiveScriptEventConsumer.Name="ConsumerNameHere"
__PROPERTY_COUNT : 8
__DERIVATION : {__EventConsumer, __IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHere"
CreatorSID : {1, 5, 0, 0...}
KillTimeout : 0
MachineName :
MaximumQueueSize :
Name : ConsumerNameHere
ScriptFilename :
ScriptingEngine : VBScript
ScriptText : Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : __FilterToConsumerBinding
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __FilterToConsumerBinding.Consumer="\\WIN7-IT3\ROOT\Subscription:ActiveS
criptEventConsumer.Name=\"ConsumerNameHere\"",Filter="\\WIN7-IT3\ROOT\Su
bscription:__EventFilter.Name=\"EventFilterNameHere\""
__PROPERTY_COUNT : 7
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:__FilterToConsumerBinding.Consumer="\\WIN7-IT
3\ROOT\Subscription:ActiveScriptEventConsumer.Name=\"ConsumerNameHere\"",F
ilter="\\WIN7-IT3\ROOT\Subscription:__EventFilter.Name=\"EventFilterName
Here\""
Consumer : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHer
e"
CreatorSID : {1, 5, 0, 0...}
DeliverSynchronously : False
DeliveryQoS :
Filter : \WIN7-IT3\ROOT\Subscription:__EventFilter.Name="EventFilterNameHere"
MaintainSecurityContext : False
SlowDownProviders : False
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : ActiveScriptEventConsumer
__SUPERCLASS : __EventConsumer
__DYNASTY : __SystemClass
__RELPATH : ActiveScriptEventConsumer.Name="ConsumerNameHere"
__PROPERTY_COUNT : 8
__DERIVATION : {__EventConsumer, __IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHere"
CreatorSID : {1, 5, 0, 0...}
KillTimeout : 0
MachineName :
MaximumQueueSize :
Name : ConsumerNameHere
ScriptFilename :
ScriptingEngine : VBScript
ScriptText : Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
PSComputerName : WIN7-IT3
在发布这个问题后不久偶然发现 this page,从中我得出我需要的查询是:
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Name='c:\test\filewatching\tester.txt'
请注意,与其他几篇在线帖子相反,对我有用的实际上是省略了 TargetInstance
的 Path
和 Drive
部分,只包含了完整路径和名称我要看的文件
这对我有用,因为我只会观看 1 个特定文件。如果您需要使用此方法观看多个文件,则需要注册多个订阅。
注册文件修改观察器的完整代码:
#WQL
$query = @"
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Name='c:\test\filewatching\tester.txt'
"@
$instanceFilter = ([WMICLASS]"\$Computername\root\subscription:__EventFilter").CreateInstance()
$instanceFilter.QueryLanguage = 'WQL'
$instanceFilter.Query = $query
$instanceFilter.Name = 'EventFilterNameHere'
$instanceFilter.EventNameSpace = 'root/CIMV2'
$result = $instanceFilter.Put()
# Consumer
$script =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
"@
$instanceConsumer = ([wmiclass]"\$Computername\root\subscription:ActiveScriptEventConsumer").CreateInstance()
$instanceConsumer.Name = 'ConsumerNameHere'
$instanceConsumer.ScriptingEngine = 'VBScript'
$instanceConsumer.ScriptFilename = ''
$instanceConsumer.ScriptText = $script
$instanceConsumer.Put()
# Binding
[object]$Filter = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventFilter | Sort Name)
[object]$Consumer = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventConsumer | Sort Name)
$instanceBinding = ([wmiclass]"\$Computername\root\subscription:__FilterToConsumerBinding").CreateInstance()
$instanceBinding.Filter = $Filter
$instanceBinding.Consumer = $Consumer
$instanceBinding.Put()
您需要将消费者和过滤器的路径附加到活页夹
而不是系统中的每个 filter\consumer
$result = $instanceFilter.Put()
$filterPath = $result.Path
$result = $instanceConsumer.Put()
$consumerPath = $result.Path
$bind.Filter = $filterPath
$bind.Consumer = $consumerPath
我正在尝试通过此查询使用 WQL
订阅修改特定文件的事件:
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA "CIM_DataFile" AND TargetInstance.Drive="C:" AND TargetInstace.Path="\test\filewatching\"
我可以成功注册事件(见底部的输出)并且可以看到它与我注册的脚本(消费者)绑定。
但是,当我修改 C:\test\filewatching\
中的文件时,脚本不会 运行。
这是在同一文件夹中注册文件创建事件的代码,并且有效:
#WQL
$query = @"
SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA "Cim_DirectoryContainsFile" AND TargetInstance.GroupComponent="Win32_Directory.Name='C:\test\filewatching'"
"@
$instanceFilter = ([WMICLASS]"\$Computername\root\subscription:__EventFilter").CreateInstance()
$instanceFilter.QueryLanguage = 'WQL'
$instanceFilter.Query = $query
$instanceFilter.Name = 'EventFilterNameHere'
$instanceFilter.EventNameSpace = 'root/CIMV2'
$result = $instanceFilter.Put()
# Consumer
$script =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
"@
$instanceConsumer = ([wmiclass]"\$Computername\root\subscription:ActiveScriptEventConsumer").CreateInstance()
$instanceConsumer.Name = 'ConsumerNameHere'
$instanceConsumer.ScriptingEngine = 'VBScript'
$instanceConsumer.ScriptFilename = ''
$instanceConsumer.ScriptText = $script
$instanceConsumer.Put()
# Binding
[object]$Filter = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventFilter | Sort Name)
[object]$Consumer = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventConsumer | Sort Name)
$instanceBinding = ([wmiclass]"\$Computername\root\subscription:__FilterToConsumerBinding").CreateInstance()
$instanceBinding.Filter = $Filter
$instanceBinding.Consumer = $Consumer
$instanceBinding.Put()
所以我知道我的 PowerShell 没有问题。这让我觉得我的查询一定是错误的。
我已经尝试对上述 InstanceModificationEvent
查询进行一些调整,但没有成功。 (这些调整包括将 C:
更改为 C
或从 TargetInstace.Path
中删除 \
等内容)。
我需要此订阅是永久的,并且如果 PC 打开或关闭则无法重置 - 这就是我使用 WQL 的原因。如果有人可以建议另一种实现相同目标的方法或如何解决我的查询,我将永远感激不已!
运行脚本后的输出:
Path : \WIN7-IT3\root\subscription:ActiveScriptEventConsumer.Name="Co
nsumerNameHere"
RelativePath : ActiveScriptEventConsumer.Name="ConsumerNameHere"
Server : WIN7-IT3
NamespacePath : root\subscription
ClassName : ActiveScriptEventConsumer
IsClass : False
IsInstance : True
IsSingleton : False
Path : \WIN7-IT3\root\subscription:__FilterToConsumerBinding.Consumer
="\\WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Na
me=\"ConsumerNameHere\"",Filter="\\WIN7-IT3\ROOT\Subscripti
on:__EventFilter.Name=\"EventFilterNameHere\""
RelativePath : __FilterToConsumerBinding.Consumer="\\WIN7-IT3\ROOT\Subscri
ption:ActiveScriptEventConsumer.Name=\"ConsumerNameHere\"",Filt
er="\\WIN7-IT3\ROOT\Subscription:__EventFilter.Name=\"Event
FilterNameHere\""
Server : WIN7-IT3
NamespacePath : root\subscription
ClassName : __FilterToConsumerBinding
IsClass : False
IsInstance : True
IsSingleton : False
正在查询 WMI 订阅:
Get-WmiObject -Namespace root\Subscription -Class __Eventfilter
Get-WMIObject -Namespace root\Subscription -Class __EventConsumer
Get-WMIObject -Namespace root\Subscription -Class __FilterToConsumerBinding
Get-WMIObject -Namespace root\Subscription -Class ActiveScriptEventConsumer
查询后输出:
__GENUS : 2
__CLASS : __EventFilter
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __EventFilter.Name="EventFilterNameHere"
__PROPERTY_COUNT : 6
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:__EventFilter.Name="EventFilterNameHere"
CreatorSID : {1, 5, 0, 0...}
EventAccess :
EventNamespace : root/CIMV2
Name : EventFilterNameHere
Query : SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA
"CIM_DataFile" AND TargetInstance.Drive="C:" AND
TargetInstace.Path="\test\filewatching\"
QueryLanguage : WQL
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : ActiveScriptEventConsumer
__SUPERCLASS : __EventConsumer
__DYNASTY : __SystemClass
__RELPATH : ActiveScriptEventConsumer.Name="ConsumerNameHere"
__PROPERTY_COUNT : 8
__DERIVATION : {__EventConsumer, __IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHere"
CreatorSID : {1, 5, 0, 0...}
KillTimeout : 0
MachineName :
MaximumQueueSize :
Name : ConsumerNameHere
ScriptFilename :
ScriptingEngine : VBScript
ScriptText : Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : __FilterToConsumerBinding
__SUPERCLASS : __IndicationRelated
__DYNASTY : __SystemClass
__RELPATH : __FilterToConsumerBinding.Consumer="\\WIN7-IT3\ROOT\Subscription:ActiveS
criptEventConsumer.Name=\"ConsumerNameHere\"",Filter="\\WIN7-IT3\ROOT\Su
bscription:__EventFilter.Name=\"EventFilterNameHere\""
__PROPERTY_COUNT : 7
__DERIVATION : {__IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:__FilterToConsumerBinding.Consumer="\\WIN7-IT
3\ROOT\Subscription:ActiveScriptEventConsumer.Name=\"ConsumerNameHere\"",F
ilter="\\WIN7-IT3\ROOT\Subscription:__EventFilter.Name=\"EventFilterName
Here\""
Consumer : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHer
e"
CreatorSID : {1, 5, 0, 0...}
DeliverSynchronously : False
DeliveryQoS :
Filter : \WIN7-IT3\ROOT\Subscription:__EventFilter.Name="EventFilterNameHere"
MaintainSecurityContext : False
SlowDownProviders : False
PSComputerName : WIN7-IT3
__GENUS : 2
__CLASS : ActiveScriptEventConsumer
__SUPERCLASS : __EventConsumer
__DYNASTY : __SystemClass
__RELPATH : ActiveScriptEventConsumer.Name="ConsumerNameHere"
__PROPERTY_COUNT : 8
__DERIVATION : {__EventConsumer, __IndicationRelated, __SystemClass}
__SERVER : WIN7-IT3
__NAMESPACE : ROOT\Subscription
__PATH : \WIN7-IT3\ROOT\Subscription:ActiveScriptEventConsumer.Name="ConsumerNameHere"
CreatorSID : {1, 5, 0, 0...}
KillTimeout : 0
MachineName :
MaximumQueueSize :
Name : ConsumerNameHere
ScriptFilename :
ScriptingEngine : VBScript
ScriptText : Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
PSComputerName : WIN7-IT3
在发布这个问题后不久偶然发现 this page,从中我得出我需要的查询是:
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Name='c:\test\filewatching\tester.txt'
请注意,与其他几篇在线帖子相反,对我有用的实际上是省略了 TargetInstance
的 Path
和 Drive
部分,只包含了完整路径和名称我要看的文件
这对我有用,因为我只会观看 1 个特定文件。如果您需要使用此方法观看多个文件,则需要注册多个订阅。
注册文件修改观察器的完整代码:
#WQL
$query = @"
SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'CIM_DataFile' AND TargetInstance.Name='c:\test\filewatching\tester.txt'
"@
$instanceFilter = ([WMICLASS]"\$Computername\root\subscription:__EventFilter").CreateInstance()
$instanceFilter.QueryLanguage = 'WQL'
$instanceFilter.Query = $query
$instanceFilter.Name = 'EventFilterNameHere'
$instanceFilter.EventNameSpace = 'root/CIMV2'
$result = $instanceFilter.Put()
# Consumer
$script =
@"
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile("c:\test\filewatching\Log.log", 8, True)
objFile.WriteLine "New File Created"
objFile.Close
"@
$instanceConsumer = ([wmiclass]"\$Computername\root\subscription:ActiveScriptEventConsumer").CreateInstance()
$instanceConsumer.Name = 'ConsumerNameHere'
$instanceConsumer.ScriptingEngine = 'VBScript'
$instanceConsumer.ScriptFilename = ''
$instanceConsumer.ScriptText = $script
$instanceConsumer.Put()
# Binding
[object]$Filter = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventFilter | Sort Name)
[object]$Consumer = (Get-WMIObject -Computername $Computername -Namespace root\Subscription -Class __EventConsumer | Sort Name)
$instanceBinding = ([wmiclass]"\$Computername\root\subscription:__FilterToConsumerBinding").CreateInstance()
$instanceBinding.Filter = $Filter
$instanceBinding.Consumer = $Consumer
$instanceBinding.Put()
您需要将消费者和过滤器的路径附加到活页夹 而不是系统中的每个 filter\consumer
$result = $instanceFilter.Put()
$filterPath = $result.Path
$result = $instanceConsumer.Put()
$consumerPath = $result.Path
$bind.Filter = $filterPath
$bind.Consumer = $consumerPath