AD域环境下打印机批量部署失败的排查手记

问题背景

周二上午9点刚过,行政部的李姐就冲进IT办公室:”王工,3楼、4楼新装的打印机一台都用不了,上周不是已经批量推送过去了吗?”

事情要从一周前说起。我们公司上周搬迁,3楼、4楼办公区新增了6台网络打印机(HP M438n),按计划通过组策略(GPO)批量推送到对应的计算机OU。理论上只要机器重启或者刷新策略,就能自动映射好打印机。但现实是——80台机器里只有30台正常,剩下50台分布在3楼、4楼全部报错。

影响范围不算小:3楼、4楼两个楼层加起来80个工位,行政、财务、销售部门都在这一片,业务基本停摆。紧急程度:P1(影响业务),需要在上午11点前给一个临时方案,下午前彻底解决。

故障现象

正常的那30台机器,登录后能在”设备和打印机”里看到新增的6台打印机,能正常打印。

出问题的50台机器表现完全一致:

  1. 打开”设备和打印机”,6台打印机一台都不显示
  2. 手动运行\\printserver\PrintInstaller\setup.exe安装驱动,提示:
    1
    Windows 无法连接到打印机,操作失败,错误为 0x0000011b
  3. 打开printmanagement.msc(打印管理),本机的”打印机”列表是空的,没有任何队列
  4. 事件查看器 → 系统日志里刷出大量红色错误:
    1
    2
    错误  application  0  0  PrintService
    Spooler 正在关闭。
    每隔2-3分钟就重复一次。

看到 0x0000011b 第一反应是今年闹得沸沸扬扬的 PrintNightmare 漏洞补丁导致的打印共享问题。但我们推的是本地驱动直连(IP直连),不应该走 SMB 共享才对。这个直觉告诉我——根因可能和漏洞补丁没关系,得另找思路。

排查过程

第一步:先解决”能不能用”的问题(止血)

50台机器全靠脚本临时修不现实。我先让3楼前台、4楼前台、销售部主管这3台”关键岗”电脑单独处理:

1
2
3
4
5
# 临时方案:手动添加打印机
# 走IPP端口直连,不依赖SMB共享
Add-Printer -Name "HP-M438n-3F-01" `
-DriverName "HP Universal Printing PCL 6" `
-PortName "IP_192.168.30.201"

测试发现:走IP直连可以装上。所以问题不在打印机本身,也不在网络层面(ICMP、9100端口都通)。问题卡在”批量推送”这个动作上。

第二步:检查GPO是否真的下发到机器

在出问题的机器上跑:

1
gpresult /h C:\gpo_report.html

打开报告一看——计算机配置里包含了我们那条打印机映射策略,OU归属也正确。策略是有的。

第三步:手动强制刷新策略

1
gpupdate /force

执行完重启,问题依旧。说明GPO能下发到,但执行动作的时候挂了。

第四步:去看脚本到底干了啥

打印机映射脚本本质上是个开机脚本,用 rundll32 printui.dll 走PointAndPrint模式:

1
rundll32 printui.dll,PrintUIEntry /in /n "\\printserver\HP-M438n-3F-01"

这里有 \\printserver\ 也就是说,脚本虽然最终连的是IP直连打印机,但驱动安装阶段还是要回到打印服务器去拉驱动文件。

但前面排过 SMB 没通吗?我们马上测一下:

1
net view \\printserver

提示:发生系统错误 53。找不到网络路径。

哦豁,问题就出在这。50台机器都 ping 不通 printserver 这个主机名(DNS解析失败),而那30台正常的机器是上个月搬迁前就装好的——它们的本地 DNS 缓存里还残留着 printserver 的旧解析记录(指向搬迁前的服务器IP),所以”看起来”能工作。

第五步:定位 DNS 解析失败原因

在出问题的机器上:

1
nslookup printserver

返回:

1
2
3
服务器:  UnKnown
Address: 192.168.10.5
*** UnKnown 找不到 printserver: Non-existent domain

DNS服务器是我们内部的AD DC(192.168.10.5),正常的。但 printserver 这条A记录不在了

立即去DNS管理器查看:果然,搬迁那天IT同事在迁移打印服务器到新IP(192.168.30.200)的时候,只改了A记录的IP值,没保存。但诡异的是,有30台机器还能解析出来——后来查证,那30台机器在搬迁当天重启过,本地DNS缓存里有过临时解析,缓存还没过期;剩下50台上周都没重启过,今天一刷新就全暴露了。

第六步:验证修复

DNS 修复后,在一台问题机器上 ipconfig /flushdns,然后 gpupdate /force 重启——打印机全出来了。

解决方案

1. DNS 修复(治本)

在DNS管理器里:

  • 进入 printserver 的A记录,重新保存(值是对的,只是没保存成功);
  • 顺手在DHCP里给所有客户端推送 DNS 搜索域 corp.local,避免单点主机名解析;
  • printserver 加一条别名(CNAME)prt,双管齐下防止单点故障。

2. 脚本改造(治标+预防)

把脚本里所有 \\printserver\ 改成 IP 直连(\\192.168.30.200\),或者干脆全部用 Add-Printer 走IPP,彻底摆脱SMB依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 改造后的脚本(节选)
$printers = @(
@{Name="HP-M438n-3F-01"; IP="192.168.30.201"},
@{Name="HP-M438n-3F-02"; IP="192.168.30.202"},
@{Name="HP-M438n-4F-01"; IP="192.168.30.211"}
)

foreach ($p in $printers) {
$portName = "IP_$($p.IP)"
if (-not (Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue)) {
Add-PrinterPort -Name $portName -PrinterHostAddress $p.IP
}

if (-not (Get-Printer -Name $p.Name -ErrorAction SilentlyContinue)) {
Add-Printer -Name $p.Name `
-DriverName "HP Universal Printing PCL 6" `
-PortName $portName
}
}

3. 应急方案

把上面这个 PowerShell 脚本放到共享路径 \\fileserver\IT\Tools\RepairPrinters.ps1,让有问题的用户右键以管理员运行一次,先把业务恢复。

根因分析

表面看是打印机没装上,根因是变更管理没闭环

  1. 搬迁当天同事修改DNS记录时,没有验证保存结果(UI上点保存和实际写入是有区别的,UAC、域权限、AD复制延迟都可能让”看起来保存了”但实际没生效);
  2. GPO 推送脚本强依赖主机名 \\printserver\,没有兜底机制;
  3. 没有打印机连接状态的监控告警,等到用户主动报障才发现,业务影响已经扩大。

说白了,单点 DNS 故障 + 强依赖主机名 + 零监控,三连击凑齐了,事故只是时间问题。

预防措施

针对这次问题,给后续运维工作立了三条规矩:

  1. 变更后必验证:所有 DNS、DHCP、GPO 类变更必须变更前快照 + 变更后 5 分钟内 nslookup 验证,并在群内截图留痕。重要变更申请双人复核;
  2. 脚本去单点依赖:所有登录脚本、开机脚本里禁止写裸主机名,必须用 FQDN(printserver.corp.local)或 CNAME 别名,并且关键脚本增加 fallback 逻辑——主路径走不通就走IP直连;
  3. 加监控:用 Zabbix 监控关键打印机(IP在线、墨盒、卡纸)和域内关键主机名解析成功率,超过 5% 失败率自动告警。

监控盲区是最贵的盲区,这次等于交了50台机器+1个上午的学费。

总结

这次故障给团队最深的教训是:用户报障的”现象”和”根因”之间,往往隔了 3-4 层跳转。从打印机没装好 → 0x0000011b → GPO没生效 → DNS记录丢失,4步才到根因。如果一开始就盯着打印机本身(驱动、端口、网络),会浪费大量时间。

排查这种”批量出问题”的场景,**最快的破局点不是”找正常的30台和异常的50台有什么区别”,而是直接去看”异常的那批,在哪一步出错了”**。这次 nslookup printserver 这一下,5分钟定位了根因,比逐个机器查 GPO 应用日志高效得多。

运维老炮都懂的道理:先看 DNS,再看网络,最后看应用。别上来就重启服务。