Windows AD PowerShell(十):事件日志
这是 Windows AD PowerShell 学习记录的第十节。前面的章节学会了查对象、复制、DNS、SPN、Kerberos 与时间;这一节把它们连接到 Windows 事件日志:看见故障时,去哪台机器、查哪个日志、看哪些字段?
2026 年 9 月 24 日,本节在实验域控 QYNET-CORE01 上通过 VMware Tools 执行了只读查询。下方注明“实机输出”的时间、账户和错误码来自该 VM;没有为制造案例而锁定用户、修改审计策略或触发故障。日志中有 9 月 23 日的历史错误,同时当天的复制摘要仍显示 DC02 不可达;文末会将两者关联,但不在本文执行修复。
十、事件日志
10.1 先分清:事件发生在哪里
| 要查的现象 | 优先看的机器与日志 | 理由 |
|---|---|---|
| 域账户被锁定 | DC 的 Security,事件 4740 | 锁定记录可提供被锁账户和调用方计算机线索 |
| 用户在某台机器登录失败 | 发生登录的目标机器的 Security,事件 4625 | 它记录该机器上的登录失败;不能只盯 DC |
| Kerberos 预认证失败 | 处理认证的 DC 的 Security,事件 4771 | KDC 拒绝签发 TGT 时可见失败代码 |
| NTLM 凭据验证 | 验证域账户的 DC 的 Security,事件 4776 | 既可能成功,也可能失败,要看 Status |
| AD DS 错误 | DC 的 Directory Service | 复制、FSMO 和目录服务故障常在这里说明原因 |
| SYSVOL 的 DFSR 异常 | DC 的 DFS Replication | 用于跟踪 SYSVOL 复制伙伴与连接错误 |
⚠️ 查不到事件不等于事件一定没发生。 还可能是查错机器、审计策略未启用、事件已被覆盖、时间范围选错,或者事件发生在另一台 DC。先确定日志位置与审计范围,再解释“没有结果”。
10.2 查询账户锁定:4740
先按日志名与事件 ID 在服务端过滤,只取最近 20 条:
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4740} -MaxEvents 20 | Select-Object -First 2 TimeCreated,Id,LevelDisplayName
TimeCreated Id LevelDisplayName----------- -- ----------------2026/9/9 10:02:30 4740 信息2026/9/9 10:01:19 4740 信息上面是 QYNET-CORE01 实机输出节选。“信息”是事件级别,并不表示账户锁定是好事;要按 Id 和事件字段判断。若只想看最近一小时,可加 StartTime=(Get-Date).AddHours(-1),避免遍历过多旧事件:
Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4740 StartTime = (Get-Date).AddHours(-1)} -ErrorAction SilentlyContinue
# 本次查询时间段没有匹配的 4740,命令无输出“是谁锁的”:Caller Computer Name
打开 4740 详情,重点看“已锁定的帐户”和“附加信息 → 调用方计算机名”。在当前 VM 的一条真实记录里,被锁账户是 qianyue,调用方计算机名是 QYNET-USER01。
如果要批量提取,不建议靠中文或英文 Message 的文字位置做字符串截取。可以读取事件 XML 的具名字段。这里有个容易踩的坑:在 4740 的 XML 中,事件查看器显示的 Caller Computer Name 对应字段名是 TargetDomainName,不是 CallerComputerName:
$event = Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4740} -MaxEvents 1
$data = @{}([xml]$event.ToXml()).Event.EventData.Data | ForEach-Object { $data[$_.Name] = $_.InnerText}
[pscustomobject]@{ TimeCreated = $event.TimeCreated LockedAccount = $data['TargetUserName'] CallerComputerName = $data['TargetDomainName']}
TimeCreated : 2026/9/9 10:02:30LockedAccount : qianyueCallerComputerName : QYNET-USER01这是实机记录。调用方计算机名是定位线索,不一定就是最终保存旧密码的应用或最终用户设备;它也可能为空,或只显示转发请求的机器。应在该机器继续核对计划任务、Windows 服务、映射盘、凭据管理器以及邮件/VPN 客户端,并与同时间的认证事件交叉验证,不要看到 4740 就直接删除凭据。
10.3 查询登录失败:4625
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625} -MaxEvents 20 | Select-Object -First 2 TimeCreated,Id,LevelDisplayName
TimeCreated Id LevelDisplayName----------- -- ----------------2026/9/23 15:00:57 4625 信息2026/9/23 15:00:57 4625 信息以上为实机输出节选。这两条最近记录的 LogonType 是 5(服务登录),TargetUserName 为 -,状态码为 0xC000018D;不能把任何一条 4625 都解释成“用户输错密码”。
排查时至少核对:
| 字段 | 要回答的问题 |
|---|---|
TargetUserName | 哪个账户登录失败? |
LogonType | 是交互式、网络、远程交互,还是服务/计划任务登录? |
Status / SubStatus | Windows 给出的失败原因是什么? |
IpAddress / WorkstationName | 请求从哪里来?字段可能为空或显示 - |
ProcessName | 是哪个进程发起的请求? |
同样可以从 XML 取字段,避免按语言拆分 Message:
$event = Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4625} -MaxEvents 1
$data = @{}([xml]$event.ToXml()).Event.EventData.Data | ForEach-Object { $data[$_.Name] = $_.InnerText}
[pscustomobject]@{ TimeCreated = $event.TimeCreated Account = $data['TargetUserName'] LogonType = $data['LogonType'] Status = $data['Status'] SubStatus = $data['SubStatus'] Process = $data['ProcessName']}
TimeCreated : 2026/9/23 15:00:57Account : -LogonType : 5Status : 0xc000018dSubStatus : 0xc000018dProcess : C:\Windows\System32\svchost.exe以上为实机输出。日志级别 LevelDisplayName 是“信息”,但事件 ID 与 Status 表明这是登录失败。
10.4 查目录服务与 DFSR:别用英文级别名称硬匹配
原始思路是“取最近 50 条,再找错误/警告”,但下面的写法在中文 Windows 上不可靠:
# 不推荐:本机的 LevelDisplayName 实际显示“错误”“警告”,不是 Error/WarningGet-WinEvent -LogName 'Directory Service' -MaxEvents 50 | Where-Object { $_.LevelDisplayName -eq 'Error' }LevelDisplayName 会本地化。若仍想按“最近 50 条”筛选,应使用不受显示语言影响的数值 Level:2 是错误,3 是警告。
Get-WinEvent -LogName 'Directory Service' -MaxEvents 50 | Where-Object { $_.Level -eq 2 } | Select-Object -First 3 TimeCreated,Id,LevelDisplayName
TimeCreated Id LevelDisplayName----------- -- ----------------2026/9/23 16:00:40 1863 错误2026/9/23 16:00:40 1863 错误2026/9/23 16:00:40 1863 错误以上是实机输出节选。事件 1863 描述的是某些目录分区在配置的延迟间隔内未收到复制信息。这里应先核对复制状态,而不是只根据事件 ID 推断根因。
DFSR 同理:
Get-WinEvent -LogName 'DFS Replication' -MaxEvents 50 | Where-Object { $_.Level -in 2,3 } | Select-Object -First 3 TimeCreated,Id,LevelDisplayName
TimeCreated Id LevelDisplayName----------- -- ----------------2026/9/23 16:35:37 5008 错误2026/9/23 15:32:54 5008 错误2026/9/23 15:16:32 5008 错误以上为实机输出节选。其中一条 5008 指向 SYSVOL 的复制伙伴 QYNET-CORE02,错误为 1722:RPC 服务器不可用。它与复制健康篇中的 RPC 排障相连;不能只靠日志 ID 判断是网络、DNS、防火墙还是伙伴没有启动。
💡 两种筛选语义不同:
-MaxEvents 50 | Where-Object Level ...是“最近 50 条里有多少错误”;-FilterHashtable @{LogName='...'; Level=2}是“先找错误,再取最近若干条”。后者通常更适合大日志,但会找到更早的错误,不能误称为“最近 50 条中的错误”。
10.5 4625、4771、4776:不要混为一谈
| ID | 常见记录位置 | 代表什么 | 判断关键 |
|---|---|---|---|
4625 | 登录失败发生的目标机器 | 该机器上的登录失败 | LogonType、Status、SubStatus、来源地址 |
4771 | DC / KDC | Kerberos 预认证失败,KDC 未签发 TGT | FailureCode |
4776 | 验证域账户的 DC | NTLM 凭据验证尝试 | Status=0x0 为成功,非零再查失败原因 |
不是“Kerberos 密码错只看 4771,NTLM 密码错只看 4776,因此 4625 没用”。同一次尝试可能在不同机器和认证阶段留下不同事件;是否出现仍取决于实际协议、审计配置与日志保留情况。
查询近期 Kerberos 预认证失败:
$preAuthFailures = @(Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4771} -MaxEvents 20 -ErrorAction SilentlyContinue)
$preAuthFailures.Count
0这是当前 VM 的实际结果:没有查到 4771,所以本文不会编造一条 4771 实机输出。若在别的环境遇到 4771,重点看 FailureCode:
| 代码 | Kerberos 含义 | 排查方向 |
|---|---|---|
0x18 | KDC_ERR_PREAUTH_FAILED | 常见于密码错误或提交的预认证信息不匹配 |
0x12 | KDC_ERR_CLIENT_REVOKED | 检查账户是否被禁用、锁定等;不能仅凭代码断定唯一原因 |
0x17 | KDC_ERR_KEY_EXPIRED | 密码过期 |
0x25 | KRB_AP_ERR_SKEW | 时钟偏差过大,优先对比客户端与 DC 时间源和偏差 |
⚠️ 原大纲把“过期”都归到
0x12,不够准确;密码过期还应留意0x17。0x25是很强的时间线索,但仍要结合事件上下文验证,不要只改时钟而不查来源。
本机能查到 4776,但最近的验证是成功而不是失败:
$event = Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4776} -MaxEvents 1
$data = @{}([xml]$event.ToXml()).Event.EventData.Data | ForEach-Object { $data[$_.Name] = $_.InnerText}
[pscustomobject]@{ Account = $data['TargetUserName'] Status = $data['Status']}
Account : AdministratorStatus : 0x0因此 4776 的表格说明应写“NTLM 凭据验证”,不能一律写成“NTLM 凭据验证失败”。
10.6 4648:显式凭据不等于横向移动
4648 表示进程显式指定另一账户的凭据尝试登录。runas、计划任务或管理工具均可能正常触发。当前实验 VM 中就有一条来自 VMware Tools 的记录:
$event = Get-WinEvent -FilterHashtable @{ LogName = 'Security' Id = 4648} -MaxEvents 1
$data = @{}([xml]$event.ToXml()).Event.EventData.Data | ForEach-Object { $data[$_.Name] = $_.InnerText}
[pscustomobject]@{ Subject = $data['SubjectUserName'] Target = $data['TargetUserName'] Process = $data['ProcessName']}
Subject : QYNET-CORE01$Target : AdministratorProcess : C:\Program Files\VMware\VMware Tools\vmtoolsd.exe以上是实机输出。单条 4648 不是入侵证据。若非管理工作站在短时间内大量触发、进程异常,或同时出现可疑远程登录与资源访问,再结合进程路径、目标账户、目标服务器、4624/4625 等事件调查。
10.7 常用安全事件 ID 速查
| ID | 含义 | 使用时的提醒 |
|---|---|---|
4624 | 登录成功 | 看登录类型,不一定是交互式登录 |
4625 | 登录失败 | 看状态码、登录类型与发生位置 |
4648 | 使用显式凭据尝试登录 | 正常管理活动也会触发 |
4662 | 对 AD 目录对象执行操作 | 需要相应审计策略与对象 SACL;可能产生大量事件 |
4720 / 4726 | 创建 / 删除用户账户 | 看发起者与目标账户 |
4728 / 4729 | 加入 / 移出全局安全组 | 与 4732/4733 的组类型不同 |
4732 / 4733 | 加入 / 移出本地安全组 | 可涉及内置组、域本地组,仍要看目标组 |
4740 / 4767 | 账户锁定 / 解锁 | 4740 关注 Caller Computer Name |
4768 | 请求 Kerberos TGT | 成败还要看事件状态 |
4771 | Kerberos 预认证失败 | 看 FailureCode |
4776 | NTLM 凭据验证 | Status=0x0 表示成功,非零表示失败 |
5136 | AD 目录对象被修改 | 需要“审核目录服务更改”及相关对象 SACL,不保证每次修改都可见 |
💡 审计是前提。
4662、5136尤其依赖对应的高级审计策略与对象 SACL;没有记录不能证明对象一定未被操作。排障时也要注意日志覆盖和采集时间窗。
10.8 本次 VM 的真实排障线索:历史事件与当前状态
这次没有主动制造故障,但从日志看到以下历史线索:
| 日志 | ID | 时间 | 事件含义(按本次消息概括) |
|---|---|---|---|
Directory Service | 1863 | 2026/9/23 16:00 | 某些分区在设定间隔内未收到复制信息 |
Directory Service | 2092 | 2026/9/23 16:01 | 本机拥有 FSMO 角色,但重启后尚未与复制伙伴成功完成初始同步,角色暂时无法验证 |
DFS Replication | 5008 | 2026/9/23 16:35 | 无法联系 SYSVOL 复制伙伴 QYNET-CORE02,错误 1722 |
历史事件不能单独证明故障现在仍存在,于是又做了一次只读的当前状态检查:
repadmin /replsummary
源 DSA 最大增量 失败/总数 %% 错误QYNET-CORE02 06d.23h:04m:28s 5 / 5 100 (1722) RPC 服务器不可用。
目标 DSA 最大增量 失败/总数 %% 错误QYNET-CORE01 06d.23h:04m:28s 5 / 5 100 (1722) RPC 服务器不可用。
尝试检索复制信息时遇到以下操作错误:58 - QYNET-CORE02.qy.net这是 2026/9/24 10:58 的实机输出节选。它确认当时复制仍不健康,而不只是“昨天报过一次错”。本次 vmrun list 仅看到 QYNET-CORE01 运行;QYNET-CORE02 未在运行 VM 列表中。这支持优先核对 DC02 的运行状态和网络,但仍不能仅凭 VMware 列表排除它在别的宿主机运行或得出全部根因。
这里不执行强制复制、FSMO seize、清理元数据等变更操作。待 DC02 的运行状态与连接方式明确后,再按第五篇:复制健康和第六篇:DCDiag逐项验证。
10.9 本节记忆卡
- 先找机器,再找日志和 ID:4625 在登录目标机,4771/4776 看负责验证的 DC。
- 4740 看调用方计算机名;其 XML 对应字段是
TargetDomainName,不要按想象写CallerComputerName。 - 中文 Windows 不用
LevelDisplayName -eq 'Error';用Level -eq 2,警告用3。 - 4776 可以成功,
4648可以是正常操作;事件 ID 不能脱离字段和上下文定性。 - 历史日志 + 当前复测 才能判断问题是否仍在;查到 1722 后从伙伴运行状态、DNS、网络、RPC 与服务继续排查。
参考资料
- Microsoft Learn:4740 账户锁定字段
- Microsoft Learn:4625 登录失败事件
- Microsoft Learn:4771 Kerberos 预认证失败与代码
- Microsoft Learn:4648 显式凭据事件
- Microsoft Learn:目录服务更改审计
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!













