[英]System.IO.FileSystemWatcher only notifies once on edited files
该脚本使用文件系统观察程序监视蜜罐文件夹,并报告任何更改(编辑,重命名,删除或创建),然后执行某些操作。
创建,重命名和删除时,操作可以正常工作。
但是在编辑时,我只能让脚本触发一次动作。 因此,例如,如果测试设备尝试编辑honeypot文件夹上的文件,则会触发操作。 但是同一设备尝试再次编辑同一个文件或不同的文件,编辑的观察者似乎无法工作,因为没有触发操作。
所以我尝试通过任务调度程序每5分钟重置一次脚本(每5分钟启动一次脚本),但结果仍然相同。
这是代码:
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "\\vmserver2\_Do_Not_Delete_Or_Rename"
$watcher.Filter = "*.*"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline
$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }
$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername
Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcher "Created" -Action $action
Register-ObjectEvent $watcher "Changed" -Action $action
Register-ObjectEvent $watcher "Deleted" -Action $action
Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}
我对powershell很新,所以我不明白,其余事件的观察者工作,只有编辑不起作用。
你的核心逻辑是合理的。
如果将操作块简化为仅执行Write-host部分,则应始终有效。 我相信你的问题是,在第二次调用时,你得到一个你没有捕获的终止错误,作为回报,它会阻止事件触发。
尝试使用以下内容替换您的操作脚本块
$action = {
try {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline
$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }
$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername
Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}
catch {
Write-Host 'an error was thrown :(... Fortunately, it was caught.'
}
}
这应该可以解决仅触发一次的已更改事件的问题。
这是一个使用3个观察者的例子,它检查同一目录下的文件更改。 您会注意到,在计数器达到5后,3名观察者中只有2名继续正常工作。 没有产生任何错误的watcherNoError
和一个产生终止错误但是在Try catch watcherErrorsTryCatch
捕获的watcherErrorsTryCatch
。
### SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO
$PathToWatch = "\\127.0.0.1\c$\_"
$watcherNoError = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}
$watcherWithErrors = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}
$watcherErrorsTryCatch = New-Object System.IO.FileSystemWatcher -Property @{Path = $PathToWatch;Filter = '*.*';IncludeSubdirectories=$true;EnableRaisingEvents = $true}
$Global:Counter = @{
watcherNoError = 0
watcherWithErrors = 0
watcherErrorsTryCatch = 0
}
### DEFINE ACTIONS AFTER AN EVENT IS DETECTED
$action = {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
Switch ($Event.MessageData.Name) {
"NoErrors" {
$Global:Counter.watcherNoError +=1
$count = $Global:Counter.watcherNoError
}
"WithErrors" {
$Global:Counter.watcherWithErrors +=1
$count = $Global:Counter.watcherWithErrors
if ($count -eq 5) {
Write-Host 'A terminated errow will be thrown...' -ForegroundColor DarkMagenta
Throw 'oh no !'
}
}
"WithErrorsTryCatch" {
$Global:Counter.watcherErrorsTryCatch +=1
$count = $Global:Counter.watcherErrorsTryCatch
if ($count -eq 5) {
try {
Throw 'oh no !'
}
catch {
Write-Host 'error was caught... You are safe ;)' -ForegroundColor Green
}
}
}
}
$logline = "Count: $Count - $($event.MessageData.Name): $changeType, $path"
write-host $logline -ForegroundColor $Event.MessageData.ForegroundColor
}
### DECIDE WHICH EVENTS SHOULD BE WATCHED
Register-ObjectEvent $watcherNoError "Changed" -Action $action -MessageData @{Name='NoErrors';ForegroundColor='Yellow'}
Register-ObjectEvent $watcherWithErrors "Changed" -Action $action -MessageData @{Name='WithErrors';ForegroundColor='DarkMagenta'}
Register-ObjectEvent $watcherErrorsTryCatch "Changed" -Action $action -MessageData @{Name='WithErrorsTryCatch';ForegroundColor='Green'}
while ($true) {sleep 5}
$action = {
try {
$path = $Event.SourceEventArgs.FullPath
$changeType = $Event.SourceEventArgs.ChangeType
$logline = "$(Get-Date), $changeType, $path"
#Add-content "D:\log.txt" -value $logline
#write-host $logline
$targetdevice = Get-SmbOpenFile |
select clientusername, clientcomputername, path |
where {$_.Path -like 'E:\Data\Archive\_Do_Not_Delete_Or_Rename' }
$targetIP = $targetdevice.clientcomputername
$targetUser = $targetdevice.clientusername
Send-ToEmail -email "edu.bit.es@gmail.com" $targetIP
$targetUser
}
catch {
Write-Host 'an error was thrown :(... Fortunately, it was caught.'
}
}
附加说明:即使它不是您的问题的解决方案,您仍应该在该Action脚本块中放置一个try / catch,因为终止错误将停止对下一个更改的进一步处理。
要么你需要使用
Remove-Event $watcher "Changed"
在$ Action脚本块的末尾或者使用
Unregister-Event $watcher "Changed"
Register-ObjectEvent $watcher "Changed -Action $action
在$ Action脚本块的末尾。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.