1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
function Search-AuditLog { param( [Parameter(Mandatory)] [string]$LogRoot,
[string[]]$Keywords = @("Remove-", "Stop-", "Delete", "Drop", "Format"),
[datetime]$StartDate,
[datetime]$EndDate,
[string]$UserFilter,
[int]$ContextLines = 3 )
$files = Get-ChildItem -Path $LogRoot -Recurse -Filter "*.txt" -File
if ($StartDate) { $files = $files | Where-Object { $_.LastWriteTime -ge $StartDate } } if ($EndDate) { $files = $files | Where-Object { $_.LastWriteTime -le $EndDate } }
Write-Host "扫描 $($files.Count) 个审计日志文件..." -ForegroundColor Cyan
$findings = @() $pattern = ($Keywords | ForEach-Object { [regex]::Escape($_) }) -join "|"
foreach ($file in $files) { $lines = Get-Content $file.FullName -Encoding UTF8
$userLine = $lines | Where-Object { $_ -match "^Username:" } | Select-Object -First 1 $fileUser = if ($userLine -match "Username:\s*(.+)") { $Matches[1].Trim() } else { "Unknown" }
if ($UserFilter -and $fileUser -notlike "*$UserFilter*") { continue }
for ($i = 0; $i -lt $lines.Count; $i++) { if ($lines[$i] -match $pattern) { $start = [Math]::Max(0, $i - $ContextLines) $end = [Math]::Min($lines.Count - 1, $i + $ContextLines) $context = ($lines[$start..$end] | Where-Object { $_ }) -join "`n"
$findings += [PSCustomObject]@{ File = $file.FullName User = $fileUser LineNum = $i + 1 Match = $lines[$i].Trim() Context = $context Timestamp = $file.LastWriteTime } } } }
Write-Host "发现 $($findings.Count) 条敏感操作记录" ` -ForegroundColor $(if ($findings.Count -gt 0) { "Yellow" } else { "Green" })
return $findings }
function New-AuditSummaryReport { param( [Parameter(Mandatory)] [object[]]$Findings,
[string]$OutputPath = "C:\Reports\AuditSummary.html" )
$reportDir = Split-Path $OutputPath -Parent New-Item $reportDir -ItemType Directory -Force | Out-Null
$byUser = $Findings | Group-Object -Property User | Sort-Object Count -Descending $byKeyword = foreach ($f in $Findings) { foreach ($kw in @("Remove-", "Stop-", "Delete", "Drop")) { if ($f.Match -match [regex]::Escape($kw)) { [PSCustomObject]@{ Keyword = $kw; Match = $f.Match } } } } | Group-Object -Property Keyword | Sort-Object Count -Descending
$html = @" <!DOCTYPE html> <html><head><meta charset="UTF-8"><title>审计摘要报告</title> <style> body{font-family:'Segoe UI',sans-serif;margin:20px;background:#f5f6fa} h1{color:#2d3436;border-bottom:2px solid #e74c3c} h2{color:#2d3436;margin-top:30px} table{width:100%;border-collapse:collapse;margin:10px 0} th{background:#0984e3;color:white;padding:10px;text-align:left} td{padding:8px 10px;border-bottom:1px solid #dfe6e9} .summary{display:flex;gap:15px;margin:15px 0} .card{background:white;border-radius:8px;padding:15px;box-shadow:0 2px 4px rgba(0,0,0,0.1)} .card .value{font-size:24px;font-weight:bold} </style></head><body> <h1>审计摘要报告</h1> <p>生成时间:$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')</p> <div class="summary"> <div class="card"><div class="value" style="color:#e74c3c">$($Findings.Count)</div><div>敏感操作总数</div></div> <div class="card"><div class="value" style="color:#0984e3">$($byUser.Count)</div><div>涉及用户</div></div> </div> <h2>按用户统计</h2><table><tr><th>用户</th><th>操作次数</th></tr> $($byUser | ForEach-Object { "<tr><td>$($_.Name)</td><td>$($_.Count)</td></tr>" }) </table> <h2>按操作类型统计</h2><table><tr><th>关键字</th><th>次数</th></tr> $($byKeyword | ForEach-Object { "<tr><td>$($_.Name)</td><td>$($_.Count)</td></tr>" }) </table></body></html> "@
$html | Set-Content $OutputPath -Encoding UTF8 Write-Host "审计报告已生成:$OutputPath" -ForegroundColor Green }
$results = Search-AuditLog -LogRoot "C:\Logs\PowerShell\Transcripts" ` -Keywords @("Remove-", "Stop-", "Delete") ` -StartDate (Get-Date).AddDays(-7)
if ($results) { New-AuditSummaryReport -Findings $results }
|