如何在香港服务器的 Windows 多 DC 环境里,用组策略 + SYSVOL 复制,解决策略分发失败

香港机房的告警信息,把我从出租屋的床上拽起来:深圳办公区 70+ 台电脑突然收不到新下发的 GPO,登录脚本没跑、驱动没装、桌面锁屏策略回滚。用户在 Teams 里爆了,香港两台 DC(HK-DC01 / HK-DC02)都“看起来”正常,但策略只在部分机器生效。
我远程连上 HK-DC02 打开事件查看器,GroupPolicy 日志里一串黄红相间:Event ID 1058 / 1030(无法从 \domain\SYSVOL 读取 GPO),再切到 DFS Replication 日志,最刺眼的是一条:Event ID 2213——复制由于数据库错误在 C: 卷被暂停。心里“咯噔”一下:SYSVOL 复制停了,GPO 肯定会乱套。
一、环境与拓扑(带参数与配置)
1)硬件与系统
| 角色 | 服务器名 | 机房 | OS & 版本 | CPU | 内存 | 磁盘 | 网卡 | 关键服务 |
|---|---|---|---|---|---|---|---|---|
| 主 DC | HK-DC01 | HK1 | Windows Server 2019 Datacenter (1809) | Xeon Silver 4210R | 64GB | NVMe SSD 1TB(系统+数据) | 2×10GbE LACP | AD DS / DNS / DFSR |
| 辅 DC | HK-DC02 | HK1 | Windows Server 2019 Datacenter (1809) | Xeon Silver 4210R | 64GB | NVMe SSD 1TB(系统+数据) | 2×10GbE LACP | AD DS / DNS / DFSR |
| 只读 DC | SZ-RODC01 | 深圳 | Windows Server 2019 | Xeon E-2246G | 32GB | SATA SSD 512GB | 1×1GbE | RODC / DNS(转发) |
说明:SYSVOL 均在默认路径 C:\Windows\SYSVOL;域/林功能级别 2016;SYSVOL 复制已在 DFSR 阶段,非 FRS(dfsrmig /getglobalstate 显示 Eliminated)。
2)AD 站点与复制
- 站点:HK-Site(HK-DC01、HK-DC02),SZ-Site(SZ-RODC01)
- HK 内部 DC 之间延迟 0.3–0.7ms;HK⇄SZ 跨境专线延迟 18–22ms
- HK 站点内:通知触发 + 默认 15 分钟间隔
- 站点链接成本:HK-Site(100)↔ SZ-Site(200)
3)网络端口基线(对 GPO / SYSVOL 必选)
| 端口 | 协议 | 用途 |
|---|---|---|
| 53 | TCP/UDP | DNS |
| 88、464 | TCP/UDP | Kerberos |
| 135、RPC 动态端口(49152–65535) | TCP | RPC / DCOM |
| 389、636 | TCP/UDP | LDAP / LDAPS |
| 445 | TCP | SMB(\DC\SYSVOL、\DC\NETLOGON) |
| 3268、3269 | TCP | GC |
二、故障表象与第一手证据
1)客户端侧(任意受影响 PC)
gpupdate /force
# 结果:用户策略、计算机策略更新失败
gpresult /r | more
# 发现有新建的“PrinterDeploy-2024Q4”GPO 不在“已应用的 GPO 列表”中
事件查看器(客户端):
- System:Event 1058 / 1030(无法访问 \domain\SYSVOL<domain>\Policies{GUID}\gpt.ini)
- GroupPolicy:GPO 处理失败,网络路径不可用或权限不足(实际是 SYSVOL 不一致)
2)服务器侧(HK-DC02)
- DFS Replication 日志:Event 2213(在 C: 上暂停复制,等待人工恢复)
- GroupPolicy 日志:Event 7016(GPO 版本不一致,回退上一个缓存)
- 共享:\\HK-DC02\SYSVOL 可访问,但部分 GPO 的 GPT.ini 版本落后
3)GPC/GPT 版本对比(关键证据)
GPO 的“目录对象”(GPC)在 AD 里存着 versionNumber,而“文件模板”(GPT)在 SYSVOL 的 gpt.ini 里存着 Version=。两者不一致或在不同 DC 上不一致,就会出现“有的机器拿到旧策略/有的拿到新策略”的诡异行为。
我用一段 PowerShell 在 两台 DC 上比对(节选):
# 取 AD 里的 GPC 版本
$polBase = "CN=Policies,CN=System,$((Get-ADDomain).DistinguishedName)"
$gpcs = Get-ADObject -LDAPFilter "(objectClass=groupPolicyContainer)" -SearchBase $polBase -Properties displayName,versionNumber,Name |
Select-Object @{n='GPOName';e={$_.displayName}}, @{n='GUID';e={$_.Name}}, versionNumber
# 从指定 DC 的 SYSVOL 读取 GPT 版本
function Get-GPTVersionFromDC($dc){
$domain = (Get-ADDomain).DNSRoot
$root = "\\$dc\SYSVOL\$domain\Policies"
Get-ChildItem $root -Directory | ForEach-Object {
$gpt = Join-Path $_.FullName 'gpt.ini'
if (Test-Path $gpt) {
$ver = (Select-String -Path $gpt -Pattern '^Version=(\d+)$').Matches.Groups[1].Value
[pscustomobject]@{ GUID = $_.Name; DC=$dc; GPTVersion = [int]$ver }
}
}
}
$gpt01 = Get-GPTVersionFromDC 'HK-DC01'
$gpt02 = Get-GPTVersionFromDC 'HK-DC02'
$report = $gpcs | ForEach-Object {
$x1 = $gpt01 | Where-Object GUID -eq $_.GUID
$x2 = $gpt02 | Where-Object GUID -eq $_.GUID
[pscustomobject]@{
GPOName = $_.GPOName
GUID = $_.GUID
GPCVersion = $_.versionNumber
GPT_HKDC01 = $x1.GPTVersion
GPT_HKDC02 = $x2.GPTVersion
}
}
$report | Format-Table -Auto
表格(节选):
| GPOName | GUID | GPCVersion | GPT_HKDC01 | GPT_HKDC02 |
|---|---|---|---|---|
| PrinterDeploy-2024Q4 | {6F5E…} | 65542 | 65542 | 65541 |
| DesktopLock-Company | {3C21…} | 131074 | 131074 | 131074 |
结论:HK-DC02 的 SYSVOL 里,这个 GPO 的 GPT 版本落后一格(65541 vs 65542)。这和 2213 事件吻合:HK-DC02 的 DFSR 因数据库问题暂停复制,导致新改动没有同步过来。
三、快速排错清单(现场用的 10 分钟真·Checklist)
①确认 SYSVOL 使用 DFSR 而非 FRS
dfsrmig /getglobalstate → 应为 Eliminated(否则先迁移)。
②AD 复制健康度
repadmin /replsummary、repadmin /showrepl * /csv、dcdiag /test:replications。
③DNS / 时间
dcdiag /test:DNS /v;w32tm /query /status;如需:
w32tm /config /manualpeerlist:"hk.pool.ntp.org,0x9" /syncfromflags:MANUAL /update && w32tm /resync
④SYSVOL/NETLOGON 共享可见
\\HK-DC02\SYSVOL、\\HK-DC02\NETLOGON;net share。
⑤DFSR 健康与积压
dfsrdiag backlog /rgname:"Domain System Volume" /rfname:"SYSVOL Share" /smem:HK-DC01 /rmem:HK-DC02 /full
⑥DFSR 事件关键 ID
- 2213:复制因数据库错误暂停(需要手动恢复)
- 4012:等待初始同步完成(某台新加 DC 或重建后)
- 4614/4612:数据库恢复/校验阶段
⑦GPC/GPT 版本对比(如上脚本)
⑧客户端抽样 gpresult(10 台不同网段/OU)
⑨链路抖动/丢包(香港机房内 LACP、交换机端口错误包统计)
⑩快照/回滚排查(严禁对 DC 做快照恢复,防 USN Rollback)
四、修复方案(两段式:先“让车动”,再“校准四轮”)
阶段 A:让复制恢复(处理 2213)
场景:HK-DC02 的 DFSR 在 C: 卷暂停(Event 2213)。根因多数是突然断电/崩溃导致 DFSR 数据库进入保护状态。需要人工恢复。
A-1)查询卷 GUID 并恢复复制(WMIC 方式最稳妥)
在 HK-DC02(以管理员):
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig get Volume,VolumeGuid
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where "Volume='C:'" call ResumeReplication
若提示成功,等待 1–2 分钟再看 DFSR 事件,应该出现“恢复复制”的信息。随后跑一个积压观测:
dfsrdiag backlog /rgname:"Domain System Volume" /rfname:"SYSVOL Share" /smem:HK-DC01 /rmem:HK-DC02
A-2)仍不动?做一次“非权威”重建(安全的那种)
非权威(Non-Authoritative)意味着 HK-DC02 以 HK-DC01 为准,把自己的 SYSVOL 同步成和对方一致,不会把旧数据“反向污染”到对方。
步骤(HK-DC02):
①停止 DFSR 服务
Stop-Service DFSR 或 net stop dfsr
②重命名 DFSR 数据库目录(让它重建)
路径:C:\System Volume Information\DFSR\(需要管理员 + SYSTEM 权限,可用 PsExec / 或在恢复控制台操作)
做法:把 dfsr.db 所在目录改名为 dfsr.db.bak-<日期>
③启动 DFSR 服务
Start-Service DFSR
④强制拉取 AD 配置
dfsrdiag pollad
⑤观察事件:应出现 4012 → 4614 → 4602 等初始同步/收敛日志
⑥追踪积压直到 0
dfsrdiag backlog ...,或 PowerShell Get-DfsrBacklog(装了 RSAT-DFSR 模块的话)
可选的“温和预置”:若 HK-DC02 跨站点拉数据太慢,可预置(preseed) HK-DC01 的 Policies 目录到 HK-DC02(同路径)以缩短初始同步时间:
robocopy \\HK-DC01\SYSVOL\<domain>\Policies C:\Windows\SYSVOL\<domain>\Policies /MIR /COPYALL /R:2 /W:2 /XJ
注意:只在服务停止且明确做非权威时使用,避免冲突。
A-3)确认 SYSVOL 复制正常
两边 Policies 与 Scripts 中文件数量与大小一致
核心 GPO 的 gpt.ini 版本号在两边一致
dfsrdiag backlog 为 0,且 10 分钟后复查仍为 0
阶段 B:校准 GPO 版本(消除“阴阳版本”)
B-1)一致性校验脚本(双 DC 对比)
沿用前面的 PowerShell,把“异常项”筛出来:
$report | Where-Object { $_.GPT_HKDC01 -ne $_.GPT_HKDC02 -or $_.GPCVersion -ne $_.GPT_HKDC01 } |
Sort-Object GPOName | Format-Table -Auto
B-2)遇到“GPC 是新、GPT 是旧”的典型修复
打开 GPMC(组策略管理控制台),在 HK-DC01 上对异常 GPO 做一次无害变更(例如添加一个注释或切换一个值再切回),这会触发版本号 +1 并生成新文件
等 3–5 分钟,复查 gpt.ini 与 versionNumber,确保两台 DC 已一致
B-3)客户端端到端验证
找 10 台不同 OU 的 PC,执行:
gpupdate /force && gpresult /h C:\gp.html
抽查 C:\Windows\SYSVOL\...\gpt.ini 是否能访问 & 读取
登录脚本 / 打印机部署 / 锁屏策略实操验证
五、如果不是 2213:三个常见“坑位”的处理
1)初始同步卡在 4012(新加 DC 或重建后)
症状:DFSR 日志 4012“等待初始同步完成”,dfsrdiag backlog 长期非 0。
做法(以 HK-DC01 为“基准”):
- 确认 HK-DC01 的 SYSVOL 完整、GPO 正确
- 在 HK-DC02 做非权威重建(见上阶段 A-2)
若仍不收敛,检查:
- 防火墙是否放行 RPC 动态端口
- AD 站点/子网是否正确落位(HK-DC02 不能误进 SZ-Site)
- dfsrmig /getmigrationstate 确认没有残留迁移状态
2)误用 FRS 或迁移未完成
症状:dfsrmig /getglobalstate 显示 0/1/2,或事件里出现 NtFrs 相关日志。
做法:尽快完成 FRS→DFSR 迁移(分级:Start / Prepared / Redirected / Eliminated)。迁移窗口务必无人改 GPO,完成后检查 \\*\SYSVOL 指向 DFSR。
3)虚拟化快照回滚导致 USN Rollback
症状:repadmin /showrepl 有 USN rollback 警告;GPO、用户对象等变更“忽隐忽现”。
做法:遵循微软最佳实践,不要对 DC 做快照回滚。一旦发生,通常需要下线并强制重建该 DC,包括 SYSVOL 的非权威恢复与 AD 元数据清理。
六、我现场使用的“可直接复用”的脚本与命令
1)一键拉健康报告(PowerShell)
$domain = (Get-ADDomain).DNSRoot
Write-Host "=== AD Replication Summary ==="
repadmin /replsummary
Write-Host "`n=== DNS Test ==="
dcdiag /test:DNS /v
Write-Host "`n=== SYSVOL Share Check ==="
'HK-DC01','HK-DC02' | % { Test-Path "\\$_\SYSVOL\$domain\Policies" | Out-Host }
Write-Host "`n=== DFSR Backlog HK-DC01 -> HK-DC02 ==="
dfsrdiag backlog /rgname:"Domain System Volume" /rfname:"SYSVOL Share" /smem:HK-DC01 /rmem:HK-DC02
2)DFSR 恢复(2213)WMIC 模板
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where "Volume='C:'" call ResumeReplication
dfsrdiag pollad
3)对比 GPC vs GPT(带导出)
$report | Export-Csv C:\Temp\GPO-Version-Compare.csv -NoTypeInformation -Encoding UTF8
4)客户端批量抽样(PSRemoting)
$targets = Get-ADComputer -Filter "Enabled -eq 'True'" -SearchBase "OU=Office,DC=contoso,DC=com" -Properties IPv4Address |
Select-Object -First 20 -ExpandProperty Name
Invoke-Command -ComputerName $targets -ScriptBlock {
gpupdate /force | Out-Null
gpresult /r | Select-String 'Applied Group Policy Objects'
}
七、稳定性加固(别再被凌晨叫醒)
1)监控与告警
| 检测项 | 方式 | 触发阈值/事件 |
|---|---|---|
| DFSR 暂停/错误 | 订阅事件日志 | 2213、4012、4612 |
| SYSVOL 不一致 | 定时跑“GPC/GPT 对比”脚本 | 发现任何差异即发告警 |
| AD 复制健康 | repadmin /replsummary 定时 |
失败率 > 0 或延迟 > 30 分钟 |
| SMB 可达性 | Test-Path \\DC\SYSVOL |
失败三次以上 |
| NTP 漂移 | w32tm /monitor |
偏差 > 120 秒 |
2)配置基线
- NTP 明确指向(香港近源 + 备用)
- GPO Central Store(ADMX 中央存储):\\domain\SYSVOL\domain\Policies\PolicyDefinitions,减少版本分歧
- 禁止对 DC 使用快照回滚;在虚拟化平台开启 VM-Generation ID 支持
- DFSR 自动恢复:评估后可设置策略允许崩溃后自动恢复(避免 2213 人工介入),但前提是你有完善监控,避免静默带病运行
八、常见问答(按我被问次数排序)
Q1:非权威恢复会不会把“正确的”GPO 覆盖没了?
A:不会。非权威恢复是让问题 DC 以健康 DC 为基准重建 SYSVOL。前提是你要确认基准 DC 的 GPO 是对的。
Q2:能不能直接手工复制 Policies 文件夹?
A:只在 DFSR 服务停止、明确要做“预置”以节省时间时,使用 robocopy /MIR。切记别在 DFSR 正常运行时硬拷贝覆盖,容易产生冲突与冲突解决文件。
Q3:为什么客户端有时能更新、有时不行?
A:因为 GPO 应用包含 LDAP 查询(GPC)和 SMB 拉取(GPT)。当不同 DC 的 SYSVOL 内容不同时,用户随机打到某台 DC,就会出现“阴阳版本”。
结尾:把“不可控”变成“可观测”
那天凌晨 4:10,我看着 dfsrdiag backlog 归零,gpt.ini 两边一致,十几台客户端的 gpresult 都出现了“PrinterDeploy-2024Q4”。我给工单加上了**“自动化比对 + 告警”**脚本,把所有关键事件和差异都绑上报警渠道。第二天早晨,用户说“昨天晚上那么快就好了?”我回了个“嗯”。
事故处理不是炫技,而是把不可控变成可观测、可预案。
这篇记录希望能让你在类似场景里更快落地:先判因,再恢复复制,再校准版本,最后把监控补齐。愿你也能在 10 分钟内,让 GPO 重回正轨。
附录:命令速查(可打印)
# 识别 DFSR 阶段
dfsrmig /getglobalstate
dfsrmig /getmigrationstate
# AD 复制健康
repadmin /replsummary
repadmin /showrepl *
dcdiag /test:replications
dcdiag /test:DNS /v
# DFSR 积压与拉取
dfsrdiag backlog /rgname:"Domain System Volume" /rfname:"SYSVOL Share" /smem:HK-DC01 /rmem:HK-DC02
dfsrdiag pollad
# 2213 恢复
wmic /namespace:\\root\microsoftdfs path dfsrVolumeConfig where "Volume='C:'" call ResumeReplication
# 服务控制
net stop dfsr
net start dfsr
# GPO 对比(思路)
- AD:CN=Policies,CN=System,<DN> 里的 versionNumber
- 文件:\\<DC>\SYSVOL\<domain>\Policies\<GUID>\gpt.ini 的 Version=
# 客户端验证
gpupdate /force
gpresult /h C:\gp.html