求PowerShell脚本:对比已导出事件日志与新数据,仅导出不匹配项
解决PowerShell事件日志增量导出问题
原脚本的核心问题在于数组对比逻辑错误,无法准确识别未导出的新事件日志。以下是修正后的脚本,实现仅导出CSV文件中未存在的新事件:
$csvPath = "C:\eventlogs.csv" $existingRecords = @() # 检查CSV文件是否存在,避免首次运行报错 if (Test-Path -Path $csvPath) { $existingRecords = Import-Csv -Path $csvPath | Select-Object -ExpandProperty EventRecordID # 存入哈希集合提升查找效率 $existingIDs = [HashSet[string]]$existingRecords } $filter = "*[System[EventID=4740 and Provider[@Name='Microsoft-Windows-Security-Auditing']]]" $result = Get-WinEvent -LogName Security -FilterXPath $filter | ForEach-Object { $eventXml = ([xml]$_.ToXml()).Event [PSCustomObject]@{ EventRecordID = $eventXml.System.EventRecordID EventID = $eventXml.System.EventID TimeCreated = $eventXml.System.TimeCreated.SystemTime -replace '\.\d+.*$' Computer = $eventXml.System.Computer TargetUserName = ($eventXml.EventData.Data | Where-Object { $_.Name -eq "TargetUserName" }).'#text' SubjectUserName = ($eventXml.EventData.Data | Where-Object { $_.Name -eq "SubjectUserName" }).'#text' HOSTName = ($eventXml.EventData.Data | Where-Object { $_.Name -eq "TargetDomainName" }).'#text' } } # 筛选未导出的新条目 $newEntries = $result | Where-Object { -not $existingIDs.Contains($_.EventRecordID) } # 导出数据:首次运行直接覆盖写入,后续追加 if ($newEntries) { if (Test-Path -Path $csvPath) { $newEntries | Export-Csv -Path $csvPath -NoTypeInformation -Append } else { $newEntries | Export-Csv -Path $csvPath -NoTypeInformation } }
关键改进点
- 容错处理:增加CSV文件存在性检查,解决首次运行时
Import-Csv的报错问题 - 高效查找:使用
HashSet存储已导出的EventRecordID,相比数组对比大幅提升查找速度,尤其适合日志量大的场景 - 准确筛选:通过
Contains方法精准判断单条日志的ID是否已存在,避免原脚本中-notmatch的正则匹配逻辑错误 - 兼容首次运行:首次运行CSV不存在时直接导出所有数据,后续运行仅追加新增条目
内容的提问来源于stack exchange,提问作者Arunkumar
相关产品推荐
相关产品推荐

