我是脚本编写方面的新手,所以请耐心等待。我正在尝试创建一个脚本来监视添加到服务器上所有文件共享的诱饵文件。当脚本发现文件被修改时,它将阻止对进行修改的用户的访问并发送电子邮件。除了 FileSystemWatcher 之外,该脚本似乎工作正常。它只会监控最后一个共享。我看到了similar post在这里,但对答案感到困惑。有人可以帮我完成为每个诱饵文件创建 FileSystemWatcher 的任务吗?我还希望获得有关如何以其他方式改进脚本的任何意见。非常感谢您的帮助。
$to = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="72181d1732101e1d055c111d1f" rel="noreferrer noopener nofollow">[email protected]</a>"
$File = "test.txt"
$FilePath = "C:\temp"
$md5 = new-object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
## SEND MAIL FUNCTION
function sendMail($s, $to) {
$smtpServer = "mail.nowhere.com"
$smtpFrom = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c9a8a5acbbbd89a7a6bea1acbbace7aaa6a4" rel="noreferrer noopener nofollow">[email protected]</a>"
$smtpTo = $to
$messageSubject = $s[0]
$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $false
$message.Body = $s[1]
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.Send($message)
}
## Get a list of shares and Perform tasks on each location.
$cryptopaths = Get-WmiObject -Class win32_share -filter "Type=0 AND name like '%[^$]'" | ForEach ($_.Path) {
$cryptopath = $_.Path
## Copy the bait file to the share location
Copy $FilePath\$File $cryptopath\$File -Force
##Get files hash
Try {
$Origin = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$FilePath\$File")))
$Copy = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))
}
##Error on reading hash
Catch {
echo "error reading $CryptoPath\$File"
}
## If files don't match, then Send messaged and quit
if (Compare-Object $Origin $Copy){
## files don't match
$subject = "Error logged on $CryptoPath\$File by $env:username on $env:computername"
$body = "The original file does not match the witness file. Aborting monitor script."
$email =@($subject,$body)
sendMail -s $email -to "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6103040f5353210f0e16090413044f020e0c" rel="noreferrer noopener nofollow">[email protected]</a>"
Exit
}
## CREATE WATCHER ON DIRECTORY
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $CryptoPath
$watcher.Filter = $File
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $false
$watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName
}
## Execute Watcher
while($TRUE){
$result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::Changed `
-bor [System.IO.WatcherChangeTypes]::Renamed `
-bor [System.IO.WatcherChangeTypes]::Deleted `
-bor [System.IO.WatcherChangeTypes]::Created, 1000);
if ($result.TimedOut){
continue;
}
if ($result.Name -eq $File) {
### Make sure the files do not match
try {
$FileCheck = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes("$CryptoPath\$File")))
if (Compare-Object $Origin $FileCheck){
## files don't match
$body = "Witness file $FilePath\$File on $env:computername has been modified."
}
}
catch {
## file deleted
$body = "Witness file $FilePath\$File on $env:computername has been deleted"
}
finally {
## Deny owner of changed file access to shares and disconnect their open sessions. Send email alert
Get-Acl "$CryptoPath\$File" | foreach ($_.Owner) {
Get-SmbShare | Block-SmbShareAccess –AccountName $_.Owner
Close-SmbSession –ClientUserName $_.Owner
}
$subject = "EMERGENCY ON FILE SERVER -- $FilePath\$File by $env:username on $env:computername"
$email =@($subject,$body)
sendMail -s $email -to "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3c5e59520e0e7c52534b54594e59125f5351" rel="noreferrer noopener nofollow">[email protected]</a>"
sendMail -s $email -to "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4075757575757575757575003438346e22252c2c6e2321" rel="noreferrer noopener nofollow">[email protected]</a>"
Exit
}
}
}
最佳答案
问题在于您在循环 (ForEach ($_.Path) {}
) 中创建 FileSystemWatcher
实例,但将它们分配给同一个变量 $watcher
,每次都会覆盖之前的引用。一旦脱离循环,您就可以使用 $watcher
变量,该变量引用您创建的 last FileSystemWatcher
实例,这就是您收到通知的原因仅最后一个文件。
要使其正常工作,您应该使用允许存储多个引用的类型——即数组。示例:
$watchers = @();
...
$watcher = New-Object System.IO.FileSystemWatcher;
...
$watchers += $watcher;
此外,我建议使用基于事件处理程序/回调/委托(delegate)的方法,而不是使用 WaitForChanged()
等待更改,因为等待多个文件系统观察程序将需要并行解决方案(嗯,理想情况下)。使用Register-ObjectEvent注册事件处理程序并特别查看此示例:http://gallery.technet.microsoft.com/scriptcenter/Powershell-FileSystemWatche-dfd7084b 。
PowerShellPack 还有一个 Start-FileSystemWatcher
cmdlet,可以很好地完成这一切,但我不确定 PowerShellPack 的总体状态。不过,它应该是 Windows 7/8 资源工具包的一部分。
关于powershell - Cryptolocker 蜜 jar FileSystemWatcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24794117/