PowerShell脚本检查文件更新单次发邮:代码排查与优化请求
PowerShell文件监控邮件脚本问题排查与修复方案
原脚本核心问题
- 日志触发逻辑完全错误:原脚本仅在当天日志文件不存在时才执行后续逻辑,一旦当天首次执行并创建日志后,后续每小时任务计划运行时都会直接跳过所有核心逻辑,完全无法检测当天后续新增的文件。
- 日期比较方式错误:将日期转为字符串进行比较,存在格式不匹配导致判断失效的风险,应该直接使用
DateTime对象进行比较。 - 空值未处理:当目标文件夹
D:\la\la为空时,$WatchDogFile会为$null,后续访问其LastWriteTime属性会直接抛出异常。 - 函数定义不合理:
WriteLog函数定义在if代码块内部,且依赖外部变量$WatchDogFile,一旦变量为空或函数在块外被调用就会出错。 - 变量命名冲突:
$TodayDate先被赋值为日期字符串,后又被赋值为DateTime对象,容易造成逻辑混淆。
修复与优化后的脚本
# 配置参数 $monitorFolder = "D:\la\la" $logFolder = "C:\Users\My\Downloads" $logFileName = "file-monitor-history.log" # 改为持久化日志,而非按天创建 $logFile = Join-Path -Path $logFolder -ChildPath $logFileName $smtpConfig = @{ To = "my@example.com" From = "my@example.com" SmtpServer = "smtp.example.com" Encoding = "UTF8" } # 确保日志文件夹存在 if (-not (Test-Path -Path $logFolder)) { New-Item -ItemType Directory -Path $logFolder | Out-Null } # 读取最后一次处理的时间 $lastProcessedTime = $null if (Test-Path -Path $logFile) { $lastLine = Get-Content -Path $logFile -Tail 1 -ErrorAction SilentlyContinue if ($lastLine -match 'File Processed on (\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2})') { if ([DateTime]::TryParseExact($matches[1], 'dd.MM.yyyy HH:mm:ss', $null, [System.Globalization.DateTimeStyles]::None, [ref]$lastProcessedTime)) { # 解析成功,无需额外操作 } } } # 获取目标文件夹中最新的文件 $latestFile = Get-ChildItem -Path $monitorFolder -File | Sort-Object -Property LastWriteTime -Descending | Select-Object -First 1 # 核心判断逻辑:有新文件且未处理过 if ($latestFile) { $latestFileTime = $latestFile.LastWriteTime # 若从未处理过,或最新文件的修改时间晚于最后处理时间,则发送邮件 if (-not $lastProcessedTime -or $latestFileTime -gt $lastProcessedTime) { # 发送邮件 $mailParams = $smtpConfig.Clone() $mailParams['Subject'] = "检测到新文件:$($latestFile.Name)" $mailParams['Body'] = @" <h2>新文件通知</h2> <p><strong>文件名:</strong>$($latestFile.Name)</p> <p><strong>文件路径:</strong>$($latestFile.FullName)</p> <p><strong>最后修改时间:</strong>$($latestFileTime.ToString('dd.MM.yyyy HH:mm'))</p> "@ $mailParams['BodyAsHtml'] = $true $mailParams['Attachment'] = $latestFile.FullName try { Send-MailMessage @mailParams # 写入日志,记录处理时间 $logEntry = "File Processed on $($latestFileTime.ToString('dd.MM.yyyy HH:mm:ss')) - File: $($latestFile.Name)" Add-Content -Path $logFile -Value $logEntry } catch { Add-Content -Path $logFile -Value "Error on $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss'): $_" } } } else { # 目标文件夹无文件时写入日志(可选) Add-Content -Path $logFile -Value "No files found in $monitorFolder at $(Get-Date -Format 'dd.MM.yyyy HH:mm:ss')" }
优化说明
- 持久化日志:将按天的日志改为单一持久化日志文件,确保所有处理记录都被保留,不会因为日期切换丢失历史处理信息。
- 日期对象比较:直接使用
DateTime对象进行时间比较,避免字符串格式带来的判断错误。 - 空值安全处理:增加对目标文件夹为空的判断,避免空引用异常;邮件发送加入
try/catch块,捕获发送失败的异常并写入日志。 - 配置集中管理:将监控路径、日志路径、SMTP配置等参数集中放在脚本开头,便于后续修改维护。
- 日志信息丰富:日志中增加文件名和错误信息,便于问题排查。
- 逻辑解耦:移除原脚本中依赖外部变量的内部函数,改为直接写入日志的逻辑,避免变量依赖问题。
内容的提问来源于stack exchange,提问作者Remphan
相关产品推荐
相关产品推荐

