如何使用 Powershell 文件观察器检测文件夹内的文件夹更改(特别是重命名)

How to detect Folder change (renaming in particular) inside a folder using Powershell file watcher

我正在使用 powershell 检测和记录文件夹内的文件夹更改(创建、重命名、删除等)。 此父文件夹以 TEMP_XYZ 格式从其他位置接收子文件夹。将此文件夹复制到此父文件夹后,该过程会自动将其重命名为 XYZ(删除后缀 TEMP_)

必须检测此更改(重命名)并将其记录在日志文件中作为

\test\folderwatch\XYZ was Renamed at 7/28/2021 2:03:00 PM

Folder TEMP_XYZ was renamed to XYZ

但是,我无法实现这一点,因为下面的代码仅适用于文件。 (txt、bmp、zip 等)

感谢任何帮助。

代码:

# specify the path to the folder you want to monitor:
$Monitorpath ="\test\folderwatch"
$Path = $Monitorpath

# specify which files you want to monitor
$FileFilter = '*'  

# specify whether you want to monitor subfolders as well:
$IncludeSubfolders = $true

# specify the file or folder properties you want to monitor:
$AttributeFilter = [IO.NotifyFilters]::FileName, [IO.NotifyFilters]::LastWrite 

try
{
  $watcher = New-Object -TypeName System.IO.FileSystemWatcher -Property @{
    Path = $Path
    #Filter = $FileFilter
    IncludeSubdirectories = $IncludeSubfolders
    NotifyFilter = $AttributeFilter
  }

  $action = {
    # change type information:
    $details = $event.SourceEventArgs
    $Name = $details.Name
    $FullPath = $details.FullPath
    $OldFullPath = $details.OldFullPath
    $OldName = $details.OldName
    $ChangeType = $details.ChangeType
    $Timestamp = $event.TimeGenerated
    $LogDate = Get-Date -format "dd-MMMM-yy"
    
    # save information to a global variable for testing purposes
    # so you can examine it later
    # MAKE SURE YOU REMOVE THIS IN PRODUCTION!**************************DO NOT USE FOR PROD**************************
    $global:all = $details
    
    $text = "{0} was {1} at {2}" -f $FullPath, $ChangeType, $Timestamp
    Write-Host ""
    Write-Host $text -ForegroundColor DarkYellow
    Add-content "\test\folder_watch_logs\watchlog_$LogDate.txt" -value $text

    switch ($ChangeType)
    {
      'Changed'  { "CHANGE" }
      'Created'  { "CREATED"}
      'Deleted'  { "DELETED"

        Write-Host "Deletion Handler Start" -ForegroundColor Gray
        Start-Sleep -Seconds 4  
        Write-Host "Deletion Handler End" -ForegroundColor Gray
      
      }
      'Renamed'  { 
        # this executes only when a file was renamed
        $text = "Folder {0} was renamed to {1}" -f $OldName, $Name
        Write-Host $text -ForegroundColor Yellow
        Add-content "test\folder_watch_logs\watchlog_$LogDate.txt" -value $text
      }
        
      # any unhandled change types surface here:
      default   { Write-Host $_ -ForegroundColor Red -BackgroundColor White ;
      Add-content "test\folder_watch_logs\watchlog_$LogDate.txt" -value $_ }
    }
  }

  $handlers = . {
    Register-ObjectEvent -InputObject $watcher -EventName Changed  -Action $action 
    Register-ObjectEvent -InputObject $watcher -EventName Created  -Action $action 
    Register-ObjectEvent -InputObject $watcher -EventName Deleted  -Action $action 
    Register-ObjectEvent -InputObject $watcher -EventName Renamed  -Action $action 
  }

  # monitoring starts now:
  $watcher.EnableRaisingEvents = $true
  $LogDate = Get-Date -format "dd-MMMM-yy"
  Write-Host "Watching for changes to $Path"
  Add-content "test\folder_watch_logs\watcherstatus.txt" -value "Watching for changes to $Path"

  # since the FileSystemWatcher is no longer blocking PowerShell
  # we need a way to pause PowerShell while being responsive to
  # incoming events. Use an endless loop to keep PowerShell busy:
  do
  {
    Wait-Event -Timeout 1

    # write a dot to indicate we are still monitoring:
    #Write-Host "." -NoNewline
        
  } while ($true)
}
finally
{
  # stop monitoring
  $watcher.EnableRaisingEvents = $false
  
  # remove the event handlers
  $handlers | ForEach-Object {
    Unregister-Event -SourceIdentifier $_.Name
  }
  
  $handlers | Remove-Job
  
  # properly dispose the FileSystemWatcher:
  $watcher.Dispose()
  $LogDate = Get-Date -format "dd-MMMM-yy"
  Write-Warning "Event Handler disabled, monitoring ends."
  Add-content "test\folder_watch_logs\watcherstatus.txt" -value "Event Handler disabled, monitoring ends."
}

//贾格比尔

调整观察者的 NotifyFilter,使其查看目录名称

$AttributeFilter = [IO.NotifyFilters]::FileName, [IO.NotifyFilters]::LastWrite, [IO.NotifyFilters]::DirectoryName  

或者如果您只对目录名称的更改感兴趣,请仅指定

$AttributeFilter = [IO.NotifyFilters]::DirectoryName  

如果您只对重命名事件感兴趣,请不要注册其他事件

  $handlers = . {
    # Remove Changed, Created, and Deleted if they are of no concern    
    # Register-ObjectEvent -InputObject $watcher -EventName Changed  -Action $action 
    # Register-ObjectEvent -InputObject $watcher -EventName Created  -Action $action 
    # Register-ObjectEvent -InputObject $watcher -EventName Deleted  -Action $action 
    Register-ObjectEvent -InputObject $watcher -EventName Renamed  -Action $action 
  }