首页/安全/等保与合规速查/PowerShell 审计:脚本块日志与转录

PowerShell 审计:脚本块日志与转录

PowerShell 常被用于管理与攻击:开启脚本块日志(事件 4104)与转录记录,可回溯执行内容;仅在需要时开启详细级别,兼顾性能与取证。

等保与合规速查安全更新于 2026-10-13

为什么要审计 PowerShell

PowerShell 是 Windows 上少见的「系统自带且能力完备」的执行环境:既是运维自动化工具,也是无文件攻击与横向移动的常用载体。默认情况下它只留下很少痕迹,因此需要显式开启脚本块日志(记录实际执行的脚本内容)、模块日志与转录(记录会话输入输出)。开启后可以通过事件回溯「谁在什么时间执行了什么代码」,这既是安全审计要求,也是事件溯源的关键数据。

基本信息

日志位置事件查看器 → 应用程序和服务日志 → Microsoft → Windows → PowerShell → Operational
传统日志Windows PowerShell 经典日志(含引擎启动/停止事件)
开启方式组策略:计算机配置 → 管理模板 → Windows 组件 → Windows PowerShell;或写入对应注册表项
关键事件400 引擎启动、403 引擎停止、4103 模块日志、4104 脚本块日志
转录位置由策略指定输出目录,默认在用户文档目录,建议统一到受控目录
性能代价脚本块日志会记录脚本原文,高频脚本场景下日志量明显上升

开启与查询

开启与查询
# 开启脚本块日志(等效于组策略设置)
New-Item -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' -Force | Out-Null
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging' `
  -Name EnableScriptBlockLogging -Value 1 -Type DWord

# 查询脚本块日志(事件 ID 4104)
Get-WinEvent -LogName "Microsoft-Windows-PowerShell/Operational" -MaxEvents 200 |
  Where-Object Id -eq 4104 |
  Select-Object -First 10 TimeCreated, Id, @{n='Message';e={$_.Message.Substring(0,[Math]::Min(120,$_.Message.Length))}}

# 按时间段定位一次可疑执行
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-PowerShell/Operational'; Id=4104;
  StartTime=(Get-Date).AddDays(-1)} | Where-Object Message -match 'Invoke-Expression|DownloadString'

常用事件 ID

ID含义用途
400引擎状态变为可用(会话启动)把一次会话的时间范围框出来
403引擎状态变为停止与 400 配对计算会话时长
4103模块日志,记录管道执行覆盖面广但噪声大,适合定向开启
4104脚本块日志,记录脚本或代码片段内容无文件攻击与混淆代码的主要线索
4105/4106脚本块开始/结束(需单独开启)需要精确执行时长时使用
600提供程序生命周期判断日志记录能力是否被停用

落地建议

  • 分级开启:服务器与域管终端开脚本块日志与转录,普通办公终端按风险决定是否开模块日志
  • 集中采集:Operational 日志容量有限,本地不采集会被后续事件覆盖,必须接入 SIEM 或日志平台
  • 权限收敛:脚本块日志可能记录含口令、连接串的明文脚本,日志读取权限要按最小必要授予
  • 配合取证:4104 记录代码内容但不记录执行输出,重要场景同时开转录以还原命令结果
  • 策略统一:域环境用组策略下发,避免逐台手工改注册表造成覆盖不一致
  • 版本差异:较新版本 PowerShell 的日志字段更完整,老系统上部分事件可能缺失,试点后再全网推开
脚本内容里常含凭据与内部地址,日志一旦外泄等同于泄露运维口令;访问控制、脱敏与留存期应纳入日志管理制度,不能因为「是安全日志」就放开读取。

易错点

  • 只开模块日志不开脚本块日志:有执行管道但没有代码内容,攻击载荷无法还原
  • 开启后不采集:本机 Operational 日志容量有限,值班后不久即被覆盖
  • 以为 4104 记录一切:脚本块日志记代码不记输出,缺少转录时无法还原实际执行结果
  • 逐台手工开策略:新装机与重装系统漏配,形成审计盲区

数据来源与参考

  • Microsoft Learn(PowerShell 日志与转录)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌