PowerShell IO.FileSystemWatcher文件服务器重启后失效的检测与重启方案
解决网络目录FileSystemWatcher服务器重启后失效的问题
核心问题原因
文件服务器重启时,原有的网络共享连接会断开,FileSystemWatcher绑定的路径变为不可访问状态,导致监视器停止工作且无法自动恢复。
检测与重启方案
1. 监听Error事件捕获失效
FileSystemWatcher在路径不可访问时会触发Error事件,通过注册该事件可直接捕获失效状态,并触发重建逻辑。
2. 定期轮询检测路径可用性
通过定时执行Test-Path检查目标网络路径是否可访问,一旦发现路径不可达,立即销毁旧监视器并重新创建。
修改后的完整脚本
# 定义监控路径与目标目录映射(注意补全文件服务器完整共享路径) $destinations = @{ "\\fileserver\location1" = "c:\destination1" "\\fileserver\location2" = "c:\destination2" } # 存储所有监视器实例,便于后续管理 $watchers = @() # 创建/重建监视器的函数 function New-Monitor { param( [string]$Path, [string]$Destination ) # 清理已存在的同名事件订阅与后台作业,避免资源泄漏 if (Get-EventSubscriber -SourceIdentifier $Path -ErrorAction SilentlyContinue) { Unregister-Event -SourceIdentifier $Path -ErrorAction SilentlyContinue Remove-Job -Name $Path -ErrorAction SilentlyContinue } if (Get-EventSubscriber -SourceIdentifier "$Path-Error" -ErrorAction SilentlyContinue) { Unregister-Event -SourceIdentifier "$Path-Error" -ErrorAction SilentlyContinue Remove-Job -Name "$Path-Error" -ErrorAction SilentlyContinue } # 创建新的FileSystemWatcher实例 $watcher = New-Object IO.FileSystemWatcher -Property @{ Path = $Path Filter = "*.*" IncludeSubdirectories = $false NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite' EnableRaisingEvents = $true } # 注册文件创建事件处理逻辑 Register-ObjectEvent $watcher -EventName Created -SourceIdentifier $Path -Action { $path = $Event.SourceEventArgs.FullPath $name = $Event.SourceEventArgs.Name $changeType = $Event.SourceEventArgs.ChangeType $timeStamp = $Event.TimeGenerated $destination = $destinations[$Event.SourceIdentifier] Write-Host "[$timeStamp] 文件 '$name' 被$changeType" Move-Item $path -Destination $destination -Force -Verbose } | Out-Null # 注册错误事件,捕获路径失效并触发重建 Register-ObjectEvent $watcher -EventName Error -SourceIdentifier "$Path-Error" -Action { $errorPath = $Event.SourceIdentifier.Replace("-Error", "") Write-Host "[$(Get-Date)] 监视器 '$errorPath' 发生错误,尝试重建..." New-Monitor -Path $errorPath -Destination $destinations[$errorPath] } | Out-Null return $watcher } # 初始化所有监视器 foreach ($location in $destinations.Keys) { $watchers += New-Monitor -Path $location -Destination $destinations[$location] } # 定期轮询检测(每5分钟检查一次路径可用性) while ($true) { foreach ($location in $destinations.Keys) { if (-not (Test-Path -Path $location -ErrorAction SilentlyContinue)) { Write-Host "[$(Get-Date)] 路径 '$location' 不可达,尝试重建监视器..." New-Monitor -Path $location -Destination $destinations[$location] } } Start-Sleep -Seconds 300 }
关键说明
- 双重保障机制:同时监听Error事件和定期轮询路径,确保不会遗漏失效场景。
- 资源清理:重建监视器前先清理旧的事件订阅与作业,避免内存泄漏。
- 路径修正:原脚本中的路径格式不完整,已补全为标准网络共享路径格式。
内容的提问来源于stack exchange,提问作者deca
相关产品推荐
相关产品推荐

