Powershell - 监控文件夹内容

Powershell - Monitoring folder Content

当创建大量文件并进行其他更改时,我希望能够在短时间内监视文件夹中的更改。

下面的代码有效,但没有捕获所有更改。

$folder = ’C:\Data’
$timeout = 1000
$FileSystemWatcher = New-Object System.IO.FileSystemWatcher $folder
Write-Host ”Press CTRL+C to abort monitoring $folder”
while ($true) {
$result = $FileSystemWatcher.WaitForChanged(‘all’, $timeout)
if ($result.TimedOut -eq $false)
{
Write-Warning (‘File {0} : {1}’ -f $result.ChangeType, $result.name)
}
}
Write-Host ’Monitoring aborted.’

如果我在 C:\Data 上使用它,它会起作用 但是 :

我创建了一个 .txt,它说了 2 次 new text document.txt。 然后我为新的 txt 填写名称并输出它 3 次。或者反过来。

请看下面

的输出

输出:

`Press CTRL+C to abort monitoring C:\Data
WARNING: File Created : New Text Document.txt
WARNING: File Changed : New Text Document.txt
WARNING: File Changed : New Text Document.txt
WARNING: File Changed : hello.txt
WARNING: File Created : New folder
WARNING: File Renamed : HiThere
WARNING: File Renamed : someTxt.txt
WARNING: File Changed : someTxt.txt
WARNING: File Changed : someTxt.txt
WARNING: File Changed : someTxt.txt
WARNING: File Deleted : someTxt.txt
WARNING: File Deleted : HiThere`

更多问题:如果我在 newtwork 驱动器上使用它,则不会捕获所有更改。 (这就是此脚本的重点,用于监视映射驱动器中的文件夹)。

在您的计算机上测试代码,只需更改文件夹路径即可。

使用 Powershell ISE 3.0

代替 while($true) 循环,你试过 "Register-ObjectEvent" 了吗?

我刚刚使用这种方法测试了我的一个脚本,可以轻松获取 2000 个空文件(在 powershell 中生成)。不幸的是,这是在本地机器上。

说明:像往常一样定义函数,然后就可以开始了。 您使用的命令是:

Start-BackupScript -WatchFolder "C:\temp\my watch folder\" -DestinationFolder "C:\temp\backup\"

脚本现在监视 "C:\temp\my watch folder\" 在该特定文件夹中创建的新文件,并将它们移动到 "C:\temp\backup\"。它还会将日期和时间附加到文件中。

假设您已经使用上述参数启动了脚本。您现在将 "hello_world.txt" 放在监视文件夹中。该脚本会将文件移动到 "C:\temp\backup\",新文件名为:"hello_world_2016-02-10_10-00-00.txt"

脚本在后台运行。如果你想知道它是怎么做的,那么使用命令:

Get-Job $backupscript -Keep

在那里你可以看到它一直在做什么。请注意 -Keep 参数将输出保留在 "log" 中,以便您稍后查看。

脚本:

function Start-BackupScript
{
  [CmdletBinding()]
  Param
  (
    [Parameter()]
    [String]$WatchFolder,
    [Parameter()]
    [String]$DestinationFolder
    )
  Process 
  {
    $filter = '*.*'                           
    $fsw = New-Object IO.FileSystemWatcher $WatchFolder, $filter -Property @{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName,     LastWrite'} 
    $action = {
      $fileMissing = $false 
      $FileInUseMessage = $false 
      $copied = $false 
      $file = Get-Item $Args.FullPath 
      $dateString = Get-Date -format "_yyyy-MM-dd_HH-mm-ss" 
      $DestinationFolder = $event.MessageData 
      $DestinationFileName = $file.basename + $dateString + $file.extension 
      $resultfilename = Join-Path $DestinationFolder $DestinationFileName 
      Write-Output ""
      while(!$copied) { 
        try { 
          Move-Item -Path $file.FullName -Destination $resultfilename -ErrorAction Stop
          $copied = $true 
        }  
        catch [System.IO.IOException] { 
          if(!$FileInUseMessage) { 
            Write-Output "$(Get-Date -Format "yyyy-MM-dd @ HH:mm:ss") - $file in use. Waiting to move file"
            $FileInUseMessage = $true 
          } 
          Start-Sleep -s 1 
        }  
        catch [System.Management.Automation.ItemNotFoundException] { 
          $fileMissing = $true 
          $copied = $true 
        } 
      } 
      if($fileMissing) { 
        Write-Output "$(Get-Date -Format "yyyy-MM-dd @ HH:mm:ss") - $file not found!"
      } else { 
        Write-Output "$(Get-Date -Format "yyyy-MM-dd @ HH:mm:ss") - Moved $file to backup! `n`tFilename: `"$resultfilename`""
      }
    }
    $backupscript = Register-ObjectEvent -InputObject $fsw -EventName "Created" -Action $action -MessageData $DestinationFolder
    Write-Host "Started. WatchFolder: `"$($WatchFolder)`" DestinationFolder: `"$($DestinationFolder)`". Job is in: `$backupscript"
  }
}

你看过 Register-WMIEvent 了吗?

像这样:

Register-WmiEvent -Query "SELECT * FROM __InstanceModificationEvent WITHIN 5 WHERE TargetInstance ISA 'CIM_DataFile' and TargetInstance.Path = '\Users\Administrator\' and targetInstance.Drive = 'C:' and (targetInstance.Extension = 'txt' or targetInstance.Extension = 'doc' or targetInstance.Extension = 'rtf') and targetInstance.LastAccessed > '$($cur)' " -sourceIdentifier "Accessor" -Action $action   `

您可以监视文件夹,然后监视文件夹中的特定扩展名。然后设置一个 PowerShell 脚本块来处理任何访问。如果您有兴趣,这里还有更多内容:https://blog.varonis.com/practical-powershell-for-it-security-part-i-file-event-monitoring/

同意上面的一些评论,即文件监控不可靠——滞后和打嗝。无论如何,希望这对您有所帮助。