打印机安装与部署(Windows 全场景)
一个技能覆盖三种场景。脚本唯一定稿在
scripts/,细分流程在references/:| 文件 | 内容 | |---|---| |
references/driver-direct-links.md| 20 大品牌驱动直链速查表——拿到型号直接套 URL 模板 curl 下载,不用爬官网 | |references/local-install.md| 本机安装全流程:定位 IP、确认型号、驱动四级降级、安装、核验、测试页、已知坑 | |references/remote-install.md| 远程单台:构建离线包、预检、开 WinRM、收凭据、部署、域环境、失败对照 | |references/self-run.md| 备选通道:本地账号 / 无 WinRM 时"推脚本过去自己跑"的完整流程、WMI 触发、清残留 | |references/testing-log.md| 历史实测记录与踩坑清单(用来判断一条结论是实测的还是推测的) |
入口路由:先解析"装给谁"(每次必读)
用户开口只说"装打印机"时,目标默认是本机,不要反问"装给谁"。只有在他给出目标标识时,才走远程分支。
第 1 步:判定目标
| 用户说法 | 判定 | 去向 |
|---|---|---|
| "装打印机" / "添加网络打印机"(没给任何目标) | 默认本机 | 本机路径 ↓ |
| 给了 IP | 先判定是打印机还是电脑(见下) | 打印机 → 本机(IP 已知,跳过发现);电脑 → 远程 |
| 给了 计算机名 | 目标电脑 | 远程路径 ↓ |
| 给了 MAC | 目标电脑(MAC 一般指电脑) | 远程路径 ↓ |
| 给了 使用者姓名 | 目标电脑,必须查资产清单 | 远程路径 ↓(先 resolve-asset.ps1) |
| 给了网段 / "整个部门都装" | 批量 | C 批量部署 |
| 只要驱动文件 | — | 驱动获取 |
本机路径(默认):扫 → 确认型号 → 给用户确认 → 装
1 扫局域网 find-printers.ps1 (9100/631/515 指纹 + SNMP + HTTP 取型号)
2 确认型号 脚本输出 Model/Vendor;取不到就问用户(机身铭牌 / 配置页)
3 给用户确认 列出候选「IP + 型号 + 厂商」,等用户点名 —— 不许自己替他选
4 走安装 [A 本机安装](#a-本机安装):驱动四级降级 → 安装 → 核验
5 测试页 另外单独确认,不能随安装一起打
find-printers.ps1 # 扫本机所有 /24 网段(默认)
find-printers.ps1 -Subnet 192.168.0.0/24 # 指定网段(跨 VLAN 时用)
find-printers.ps1 -IP 192.168.0.88 # 只探一台:判定类型 + 取型号
输出 printers.csv:IP, MAC, Class, Ports, Model, Vendor, SysDescr, HttpTitle, HttpUrl, HttpServer。
- 判存活靠打印端口,不靠 ping —— 很多打印机禁 ICMP,只扫 ping 会整机漏掉(实测本机 HP M1213nf 就是这样被漏的)
- 型号顺序:SNMP
sysDescr→ HTTP 页面 → HTTPServer头;都取不到就标(unknown),此时必须问用户 - 扫不到:换网段试;跨 VLAN / 打印机在别的网段时,直接问用户要 IP 和型号,走离线预装路径(打印机不在线也能装)
远程路径:先解析目标,再确认工作组还是域
第 1 步 解析目标
| 给的标识 | 怎么解析 | 命令 |
|---|---|---|
| IP | 先判定打印机/电脑 | find-printers.ps1 -IP <IP>(打印端口开 = 打印机) |
| 计算机名 | DNS 解析 | find-targets.ps1 -Name PC001 |
| MAC | ARP 缓存反查,未命中自动扫网段 | find-targets.ps1 -MAC 90-2b-34-a7-b2-30 |
| 姓名 | 必须有资产清单 | resolve-asset.ps1 -User "张三" |
姓名 → 电脑:没有资产清单就不能解析,不要猜。 清单是 assets.csv(User,ComputerName,IP,MAC,Department,中英文表头都认):
resolve-asset.ps1 -InitTemplate # 生成模板,让用户填
resolve-asset.ps1 -User "张三" -CredFile cred.xml # 解析 + 顺便报 5985 / 域成员 / OS
清单不存在时脚本会明确提示三种出路(要清单 / 要电脑名 IP / 先生成模板)。输出 target.csv 含 ResolvedIP, Reachable, WinRM5985, DomainJoined, Domain, OS。
第 2 步(必做):确认工作组还是域 —— 这决定连接方式,跳过必踩坑
# 发起端(本机)
Get-CimInstance Win32_ComputerSystem | Select-Object PartOfDomain, Domain, Workgroup
# 目标机
probe.ps1 -Target <FQDN或IP> -CredFile cred.xml # 输出 joined / domain / admin / 时钟偏差
| 组合 | 结论 | 连接要点 |
|---|---|---|
| 本机域成员 + 目标域成员 | 域 | 用 FQDN(Kerberos 不接受 IP);域账号须在目标机本地 Administrators;时钟偏差 <5 分钟;域账号走 WinRM 拿完整令牌,pnputil 直接成功 |
| 两端都工作组 | 工作组 | IP 连接 + TrustedHosts + 目标机本地管理员(NTLM);本地账号被 UAC 削令牌,pnputil 会失败 → 改 self-run 通道 |
| 本机工作组 + 目标域 | 拿不到票据 | Kerberos 必失败(0x8009030e);让发起端加域,或改用 Negotiate + 域账号 |
| 一端域一端工作组 | 按上面的"工作组"处理 | 走 IP + TrustedHosts,别指望 Kerberos |
第 3 步 再按需求装:单台走 B 远程安装,多台走 C 批量部署。
确认环节的硬规则
- 候选列表(IP + 型号 + 厂商)必须展示给用户并等确认,多台时不许自己挑
- 只有一台也建议确认,至少复述一次"IP + 型号"再动手
- 型号取不到就问用户,不许猜型号(猜错型号 = 下错驱动,前功尽弃)
- 测试页是独立确认项,不随安装一起打
决策树:先选场景,再动手
| 你要做什么 | 用户典型说法 | 走哪节 | |---|---|---| | 说"装打印机"没给目标 | "帮我装一下打印机" / "添加网络打印机" | 入口路由 → 本机路径 | | 给了 IP / 名 / MAC / 姓名 | "给 192.168.0.114 装" / "给张三装" | 入口路由 → 远程路径 | | 给自己这台电脑装 | "帮我装一下打印机" / "添加网络打印机" | A 本机安装 | | 给另一台电脑装 | "给 192.168.0.114 装" / "给同事电脑加打印机" | B 远程安装 | | 给一群电脑装 | "整个网段都装上" / "批量部署" | C 批量部署 | | 只要驱动文件 | "拿一下 XX 型号的驱动" / "下载驱动" | 驱动获取 → 速查表 | | 不知道打印机 IP / 型号 | "打印机 IP 是多少" | A 里的步骤 1-2 | | 拿不到驱动,只要能打 | "随便能打就行" | 驱动获取第 1 级(内置 class driver,≈10 s) |
三套环境方案(远程/批量时先确定环境):
| 环境 | 前置条件 | 凭据 | 连接方式 | 一条命令 |
|---|---|---|---|---|
| A 本机 | 无 | 本机管理员(1 次 UAC) | 本地执行 | 双击包里 install.bat |
| B 局域网(工作组) | 目标机开过 WinRM(5985) | 目标机本地管理员 | WinRM + Negotiate,需 TrustedHosts | deploy.bat -Target <IP> -PackageDir <pkg> |
| C 域 | WinRM(GPO 下发常见) | 域账号(须在目标机本地 Administrators) | WinRM + Kerberos(用 FQDN) | deploy.bat -Target <FQDN> -PackageDir <pkg> |
批量(B/C 通用):deploy-all.bat -TargetsFile targets.csv -PackageDir <pkg> -SkipNotReady
环境与工具准备(动手前对照一遍)
系统自带,无需安装
| 用途 | 命令 / 模块 | 是否需管理员 |
|---|---|---|
| 建端口 / 建队列 | Add-PrinterPort、Add-Printer、Set-Printer | 否(驱动已注册时) |
| 注册驱动到打印服务 | Add-PrinterDriver | 内置 class driver 否,第三方驱动是 |
| 第三方驱动入存储 | pnputil /add-driver | 是(1 次 UAC) |
| 展开 cab 内的驱动文件 | expand.exe -R -F:* | 否 |
| 下载 | curl(8.13+,Git Bash 自带) | 否 |
| 无头渲染破 SPA/WAF | msedge.exe --headless=new | 否 |
| 解析 INF / 解内嵌 ZIP | python 3.13 | 否 |
外部工具:只有 7-Zip 一个
解厂商驱动包只依赖 7-Zip,但要完整版(精简版解不了 RAR5 / MSI):
printer-driver/tools/7zfull_x/7z.exe ← 完整版,首选,能解全部格式
printer-driver/7zr.exe ← 精简版,只能解 7z
换机器时重新生成(约 10 秒,详见「提取:工具选错会白绕一圈」):
curl -sL -o 7zr.exe https://www.7-zip.org/a/7zr.exe
curl -sL -o 7z-x64.exe https://www.7-zip.org/a/7z2603-x64.exe
./7zr.exe x 7z-x64.exe -o./7zfull -y # → 7z.exe + 7z.dll
仅「远程给别的电脑装」才需要
走「B 远程安装」/「C 批量部署」时才需要(脚本都在本技能 scripts/ 里):
- 目标机开 WinRM(5985),
Enable-PSRemoting -Force -SkipNetworkProfileCheck - 本机 WinRM 服务 Running,且 TrustedHosts 含目标 IP(工作组环境)
- 凭据
Get-Credential | Export-Clixml存成 xml(不要用会被拦的明文ConvertTo-SecureString) - 域环境用 FQDN 连接,域账号须在目标机本地 Administrators
- 用户给的是姓名时,还需要一份
assets.csv资产清单(User,ComputerName,IP,MAC,Department); 没有就向用户要,resolve-asset.ps1 -InitTemplate可生成模板
仅「做驱动实验」才需要(VM)
跑厂商安装器、无头渲染这类有副作用的操作必须在虚拟机里做:
- Hyper-V VM + 域环境(本实验室:
corp.test,PC01 =10.99.0.20,账号CORP\itadmin) - 通道用
vm-remote-run技能(WMI/DCOM 点火 + SMB 取结果)—— 不需要宿主提权,VM 挂死也不会拖死调用方。不要用 Hyper-V PowerShell Direct
两个网络坑
- 宿主有全局代理(
http_proxy=127.0.0.1:62183)会污染结论: curl 加--noproxy '*',msedge 加--no-proxy-server - 本网络到部分站点不通(如
panasonic.*全 000):换下载主机或换区域站, 别反复重试
本机平台的限制(WorkBuddy,非 Windows 限制)
- Bash 里不能调
powershell.exe→ PowerShell 命令一律用 PowerShell 工具 - 被安全层拦截:
Start-Process -Verb RunAs、Add-Type、rundll32、reg.exe、schtasks.exe→ UAC 提权只能走 bat 自提权方案 - PowerShell 工具无 stdout → 输出用
Out-File写文件再读 - 安全层按关键字拦截:命令里出现
cmd字样就会被拒,换写法绕开
权限规则(重要,实测修订)
- 不需要管理员:
Add-PrinterPort、Add-Printer(前提:驱动已注册到打印服务)、Set-Printer、Remove-PrinterPort、WScript.Network.SetDefaultPrinter - 不需要管理员(新增):
Add-PrinterDriver -Name "Microsoft PCL6 Class Driver"/"Microsoft IPP Class Driver"—— Windows 内置 class driver 注册无需提权,实测通过。这是唯一真正的「零下载 + 零授权」路径。 - 需要管理员(1 次 UAC):
pnputil /add-driver(第三方驱动入存储)、Add-PrinterDriver(第三方驱动注册到打印服务) - 关键坑 1:
pnputil只把驱动放进驱动存储,不注册到打印服务。第三方驱动必须再执行Add-PrinterDriver -Name "<INF中的型号名>",否则Add-Printer报"指定的驱动程序不存在"。 - 关键坑 2:下载驱动不需要管理员,但安装第三方驱动一定需要一次管理员。只有 Windows 内置/inbox 驱动能免授权安装。
驱动获取:先算成本,再动手
20 大品牌直链速查表见
references/driver-direct-links.md—— 拿到型号先查那张表, 里面有每家的 URL 模板、怎么取当前文件名、包类型和一句话坑(20/20 实测打通)。 本节只讲判断顺序和通用手法。
默认顺序(快 → 慢):
| 顺序 | 手段 | 耗时 | 什么时候用 | |---|---|---|---| | 0 | 本机已有 / 本地库缓存 | ≈1 s | 永远先查 | | 1 | Windows 内置 class driver | ≈10 s | 只要能打就行 | | 2 | 厂商 UPD 通用驱动 | 30–60 s | 一个包覆盖几十个型号,性价比最高 | | 3 | 按品牌套直链配方 | 1–5 min | 需要装订/双面/计费等厂商功能 |
第 0 步别跳过:打印服务已注册 → 全程无 UAC;驱动存储有包 → 跳过下载(查询命令见步骤 3)。
关键认知:找链才是瓶颈,下载不是
各厂商找链难度差异极大(可程序化的约 5 秒,需 JS 渲染的 60–120 秒), 而下载通常只有 5–30 秒(实测 3–11 MB/s)。所以优先选"直链可得性好"的品牌路径, 别一上来就爬官网首页。
品牌 → 直链(20 家完整配方见 references/driver-direct-links.md)
- ★ 明文静态直链(curl 直接下):Kyocera / Pantum / KM / Xerox / Dell / Toshiba / Riso / 映美 / Panasonic / OKI / Samsung / HP / Lexmark
- ⚡ 一次接口或详情页取链:Lenovo / Epson / Canon / Fujifilm / Sharp / Ricoh / Brother
五个省时间的判断(每条都是踩出来的):
- 品牌站全封时先问"这业务是不是被卖了" —— 三星打印机已归 HP,驱动在
ftp.hp.com/printers/SS/ - 中国站可能是空壳 —— KM、Riso 的中国站都没文件,换日本站 / 全球站
- 官网被 WAF 封 ≠ 下载主机被封 —— Xerox 的
support.xerox.com403,但download.support.xerox.com是裸 Apache - 文件名会下架 —— HP 老直链现已 404,不要硬编码完整 URL,按模板 + 当前文件名拼
- 型号包不一定有 Windows 驱动 —— Dell 2330d 的 "Print driver.zip" 解出来全是 macOS
.dmg
提取与找 INF(详细手法见 references/driver-direct-links.md 第三节)
- 只用完整版
7z.exe(能解全部格式,含 RAR5 / MSI)。精简版7zr.exe解不了 zip/RAR/MSI, 会报Cannot open the file as archive—— 别误判成"私有格式" - 换机器现造(约 10 秒):
curl -sL -o 7zr.exe https://www.7-zip.org/a/7zr.exe→curl -sL -o 7z-x64.exe https://www.7-zip.org/a/7z2603-x64.exe→./7zr.exe x 7z-x64.exe -o./7zfull -y(→7z.exe+7z.dll) - 文件头是
MZ但 7z 打不开 → 搜内嵌签名Rar!/PK/7z¼¯/MSCF,SFX stub 后面就是真身 - 提取比运行快 84 倍且无副作用(Lenovo 21.78 MB:
7z x0.82 s vs 跑安装器/s69.3 s + 弹窗)。 绝不要运行厂商安装器(真需要时必须在 VM 里做) - 按内容找 INF,别按扩展名:
grep -rl -a "Class=Printer" <解包目录>; 认准Class = Printer(同包里Class = USB的是配套工具);驱动名在[Strings]段
装不上时先查这三个(都不是包坏了):
- cat 名不对 → 必须按 INF 的
CatalogFile=取(Riso 的 INF 叫RISODRV.INF,cat 却是RC20.CAT) - 驱动在 cab 里 →
[SourceDisksNames]写PRINTER.cab时,先expand -R -F:* PRINTER.cab <inf目录> - 签名证书未被信任 →
pnputil /force不解决,正解是把签名证书导入Cert:\LocalMachine\Root+TrustedPublisher(完整命令见速查表第三节)
站慢先测速,别急着换站
curl -r 0-5000000 -w "speed=%{speed_download}\n" <url> # 只下 5 MB
单连接限速 ≠ 网络差:Riso 单连接 27 KB/s(50 MB 要 30 分钟),12 段并发 Range 后 300 KB/s(2m55s)。 东芝 17 KB/s 同理(那次改用 1.74 MB 小包绕开)。并发也不叠加时再考虑换小包。
无头浏览器:破 SPA / WAF 的最后手段
curl 拿不到时才用,必须包硬超时(渲染 support.hp.com 实测挂死并拖死整个调用链):
msedge --headless=new --disable-gpu --no-sandbox --no-proxy-server
--user-agent='Mozilla/5.0 ... Chrome/120.0.0.0 Safari/537.36'
--user-data-dir=<独立目录> --virtual-time-budget=30000 --dump-dom <url>
--no-proxy-server必须(宿主全局代理会污染结果)Start-Process -PassThru+WaitForExit(30000)+Stop-Process,绝不能裸调- 真实超时 ≥200 s;
--dump-dom可能在 load 前返回,"超时" ≠ 失败,先看 DOM 大小 - 实证:Brother(WAF 403)→ 渲染出直链;Ricoh → 17 条直链(84.6 s);Epson → 10 个详情页
A 本机安装
1 定位 IP find-printers.ps1(打印端口指纹;不靠 ping)→ 192.168.0.88
2 确认型号 SNMP sysDescr → HTTP 页面 → Server 头;都取不到就问用户
⚠ 型号与 IP 必须给用户确认后再往下走(见「入口路由」硬规则)
3 取驱动 内置 class driver → MS Catalog → 可选更新 → 厂商直链
4 安装 建 TCP/IP 端口 → 注册驱动 → 建队列(脚本一次做完)
5 核验 Get-Printer 看 PrinterStatus=Normal
6 测试页 必须先问过用户再打
打印机不在线也能装(离线预装):端口 + 驱动 + 队列齐全,状态 Offline 属正常,通电/路由通了直接能打。
完整细节见 references/local-install.md(含每步命令、四级降级、核验、测试纪律、已知坑、厂商驱动包拆解手法、两个实战范例)。
B 远程安装
★ 首选路径:WinRM 直连(最简,先看这个)
能用这条就别用文末的 self-run。 域环境下目标机只要开了 WinRM 就够:
# 1. 会话到目标机(域账号)
$cred = Get-Credential 'CORP\itadmin'
$s = New-PSSession -ComputerName pc01.corp.test -Credential $cred
# 2. 传驱动(PowerShell 原生,不用 SMB、不用 cmdkey)
Copy-Item -Path .\driver -Destination C:\ProgramData\DrvBox\ -ToSession $s -Recurse
# 3. 4 条 cmdlet 装完
Invoke-Command -Session $s -ScriptBlock {
pnputil.exe /add-driver C:\ProgramData\DrvBox\driver\FF6V5AL.inf /install
Add-PrinterDriver -Name 'FF K538p for ApeosPort-V 7080 PCL 6'
Add-PrinterPort -Name '10.127.178.123' -PrinterHostAddress '10.127.178.123'
Add-Printer -Name 'ApeosPort-V 7080' -DriverName '...' -PortName '10.127.178.123'
}
# 4. 结果由 Invoke-Command 直接返回,不需要回传文件
脚本见 scripts/install-printer-simple.ps1(型号 / INF / 驱动名 / 队列名 / IP 全参数化)。
为什么这样就够:UAC 的远程令牌限制(LocalAccountTokenFilterPolicy)只削本地账号。域账号经 WinRM 连域成员服务器拿到的是完整令牌。实测:
who = CORP\itadmin
admin = True
loadDriver = True <- SeLoadDriverPrivilege 在线,令牌未被削弱
据此修正一条早期结论:早年写的"远程创建的进程继承非提权令牌,
pnputil必然失败" 只对本地账号成立。域账号走 WinRM 没有这个问题——self-run那套自提权是在解决一个不存在的问题。 工作组的本地账号、或目标机没开 WinRM 时,才需要它。
两条路径对比(均为实测)
| 维度 | WinRM 直连(首选) | self-run(备选) |
|---|---|---|
| 核心步骤 | 建会话 → 传驱动 → 4 条 cmdlet | 打包 → 推送 → 触发 → 轮询 → 拉回 |
| 目标机需开端口 | 仅 5985 | 445 + 135 + 49152-65535 |
| 凭据处理 | New-PSSession -Credential | cred.xml + cmdkey 映射 |
| 文件传输 | Copy-Item -ToSession | SMB 拷贝到 C$ 管理共享 |
| 提权 | 不需要 | 自提权 + 计划任务 + WMI 触发 |
| 结果获取 | 调用直接返回 | 客户端写 result.json,推送器轮询后拉回 |
| 目标机残留 | 只有驱动目录 | 脚本 + config + result + 日志 |
| 实测耗时 | 11.9 s(6.5MB)/ 30.6 s(33MB) | 22 s(6.5MB) |
多台打印机共存不需要清理
换型号 / 换 IP 直接装即可,互不影响。实测同一台机器先装 ApeosPort-V 7080 @ .123,再装 RICOH M C2510 @ .124,两个队列都在。这比"先清干净再装"省事得多——也顺带避开了文末那堆清理的坑。只有要复现"从零安装"做验收时才需要真正清零。
驱动名怎么从 INF 里取
[Manufacturer] 段指向的模型段里第一列就是驱动名,但常写成 %VAR%,要到 [Strings] 段查实际值。例(理光 PCL6.INF):
[RICOH_PROVIDER.ntamd64]
%RICOHB%=DTC6CZOLO,USBPRINT\RICOHM_C25105F10, RICOHM_C25105F10
[Strings]
RICOHB="RICOH M C2510 PCL 6"
同一个包里可能有多个 INF,要认准 Class = Printer 的那个(理光包里的 GXEAX6.inf 是 Class = USB 的组件,不是打印机驱动)。
工作组 vs 域
| 差异点 | 工作组 | 域 |
|---|---|---|
| 连接名 | IP | 优先 FQDN(Kerberos 不接受 IP;用 IP 会退化成 NTLM,仍需 TrustedHosts) |
| 认证 | NTLM + 必须 TrustedHosts | Kerberos,不需要 TrustedHosts |
| 开 WinRM | 目标机本地跑一次 | GPO:WinRM 服务 →「允许通过 WinRM 进行远程服务器管理」+ 防火墙「Windows Remote Management (HTTP-In)」 |
| 账号 | Administrator / 主机名\Administrator | DOMAIN\user 或 UPN user@domain.com |
| 账号权限 | 本地管理员 | 域账号须在目标机本地 Administrators(GPO 受限组) |
| 时钟 | 无要求 | 偏差 < 5 分钟,否则 Kerberos 直接失败 |
| HTTPS | 5985 | 有监听时加 -UseSSL(5986,自签证书已跳过校验) |
| 共享队列 | 罕见 | -SharedQueue \\PRINTSRV\Q1 -Auth CredSSP(第二跳需委派) |
核心结论:域内发起端必须也是域成员,且必须走 FQDN。 从工作组机器(拿不到域票据)或对 IP 发起,Kerberos 必然失败(0x8009030e 指定的登录会话不存在)。
连接回退链(-Auth Auto):Kerberos→FQDN → Negotiate→FQDN → Negotiate→IP(+TrustedHosts) →(-UseSSL 时)5986 两轮。TrustedHosts 是追加合并,不会覆盖用户已有配置。
域内非管理员装不了来自打印服务器的驱动(PrintNightmare 后 RestrictDriverInstallationToAdministrators 默认 1)。本方案是管理员本地装驱动,不受此限制——这也是它比"连共享队列"更可靠的原因。
完整流程(构建离线包 → 预检 → 目标机开 WinRM → 收凭据 → 部署 → 核验收尾)见 references/remote-install.md,含 SPN、CredSSP、GPO 三种下发方式、LocalsplOnly 坑。
C 批量部署
find-targets.bat -Subnet 192.168.0.0/24 -OnlyWinRM
deploy-all.bat -TargetsFile targets.csv -PackageDir C:\work\pkg -SkipNotReady
- 逐台执行,每台一份日志(
logs\deploy-<IP>.txt),最后出deploy-all-summary.csv:Target, Result, Seconds, Detail, Log -SkipNotReady:5985 没开的直接跳过,不浪费时间在关机的机器上-DryRun:只连通体检不安装,正式批量前先跑一遍最稳
实测(2 台,一开一关 WinRM):ok=0 fail=1 skipped=1,跳过与判定均正确。
驱动包要"一次打全"——架构与系统版本
install-printer.ps1 在目标机运行时自己挑驱动,所以一个包能同时伺候 32/64 位和不同代次的 Windows:
driver\x64\win10\*.inf <- Win10/11/Server2016+(build >= 10240)
driver\x64\win7\*.inf <- Win7/Server2008R2
driver\x86\...
匹配规则:OSArchitecture 决定 x64/x86;有 win* 子目录时按 build number 选代次,没槽就直接用架构目录。
只有一份驱动时用 -DriverDir(扁平布局)。
build-package.ps1 -DriverDirX64 C:\drv\pc6\x64 -DriverDirX86 C:\drv\pc6\x86 `
-OutDir C:\work\pkg -PrinterIP 10.127.178.123 `
-DriverName "FF K538p for ApeosPort-V 7080 PCL 6"
# 同架构还要分代次:对同一 -OutDir 再跑一次,换 -Slot(win10 / win7)
- 重复调用同一
-OutDir会叠加槽,package-info.txt保留全部 payload 行 - 32 位驱动名不同时加
-DriverNameX86 - 老系统
pnputil只有-a语法,脚本按 build number 自动切换(>=10240 用/add-driver)
定位目标电脑(四种方式)
find-targets.ps1 -IP 192.168.0.114 # 单个 IP(逗号分隔可多个)
find-targets.ps1 -Name PC001 # 计算机名(DNS 解析)
find-targets.ps1 -MAC 90-2b-34-a7-b2-30 # MAC:先查 ARP 缓存,未命中自动扫本机网段
resolve-asset.ps1 -User "张三" # 姓名:查资产清单 assets.csv(没有清单先 -InitTemplate)
find-targets.ps1 -Subnet 192.168.0.0/24 # 整个网段:并发 ping 扫出所有在线电脑
find-targets.ps1 -Subnet 192.168.0.0/24 -OnlyWinRM # 只留开了 WinRM 的(部署前用这个)
find-targets.ps1 -Subnet 10.0.0.0/24 -CredFile cred.xml # 附带 OS / 架构 / 域成员信息
输出 targets.csv:IP, HostName, MAC, WinRM5985, OS, Arch, DomainJoined, Domain。
-Subnet支持192.168.0.0/24、192.168.0.0 255.255.255.0、192.168.0.1-254,逗号分隔可多段- MAC 靠 ARP 缓存反查;缓存里没有就自动扫描,扫完再查一次
- 网段扫描会连打印机、网关、手机一起扫出来,用
-OnlyWinRM过滤 - 反向 DNS 解析是串行的,每台约等 5 秒;大网段嫌慢就加
-NoResolve - 超过 1024 个地址要加
-Force
实测(192.168.0.0/24,255 个地址,约 24 秒):6 台在线,其中 .114 TKECN-20191120G 5985 开、.88 是 HP 打印机、.1 是网关。
结果判读
| 日志关键字 | 含义 |
|---|---|
| DRIVER REGISTERED OK / DRIVER ALREADY REGISTERED | 驱动已进打印服务 |
| PRINTER ADDED OK / PRINTER ALREADY EXISTS | 队列建好 |
| PRINTER OFFLINE: x.x.x.x | 打印机当前不通,不是失败,通电即可用 |
| ADD-DRIVER FAILED | pnputil 成功但注册失败,检查是否管理员 |
| ADD-PRINTER FAILED | 驱动没注册或端口没建 |
| WARN: account is NOT a local administrator | 域常见,加本地管理员组再跑 |
验收"真从零装"(不是复用残留):日志里必须不带 Already exists in the system / already registered / already exists。
故障对照
| 现象 | 原因 | 处理 |
|---|---|---|
| 扫局域网扫不到打印机(明明就在网上) | 打印机禁 ICMP,ping 扫不出来;或跨 VLAN | 用 find-printers.ps1(按 9100/631/515 判存活);仍扫不到就问用户要 IP + 型号走离线预装 |
| 给了 IP,不知是打印机还是电脑 | 两种设备都可能"在线" | find-printers.ps1 -IP <IP>:打印端口开 = Printer,5985 开 = Computer |
| 用户给的是姓名,查不到机器 | 没有资产清单,姓名无法解析 | resolve-asset.ps1 -InitTemplate 生成 assets.csv 让用户填;或改问电脑名 / IP |
| 扫描出一堆不是电脑的设备 | 网关/打印机/手机也会响应 ping | -OnlyWinRM |
| MAC 查不到 | ARP 缓存里没有 | 给它 -Subnet,或让它自动扫本机网段 |
| 批量时某台 FAIL "cannot connect" | 没开 WinRM / 凭据不对 / 防火墙 | probe.bat 单独查那台 |
| 域账号连上但装不上 | 不在目标机本地 Administrators | GPO 受限组加入 BUILTIN\Administrators |
| Kerberos 报错 | 时钟偏差 >5 分钟或 SPN 缺失 | w32tm /resync;setspn -S WSMAN/<FQDN> <域>\<机器名>$ |
| 老机器(Win7)驱动装不上 | 用了 Win10 的 INF | 包里补 -Slot win7,脚本按 build 自动选 |
| 32 位机器驱动名不对 | x86 驱动名与 x64 不同 | -DriverNameX86 |
| 日志没生成 | $PSScriptRoot 在 param 默认值里为空(PS 5.1) | 已修;不要在 param 块里用自动变量拼路径 |
| SMB C$ 报系统错误 5 拒绝访问 | 不是密码错(密码错是 86/1326),是 UAC 远程令牌过滤 | 别在 SMB 上纠结,改走 WinRM |
| ConvertTo-SecureString ... -AsPlainText 被拦 | 安全层禁止明文凭据转换 | 用 Get-Credential \| Export-Clixml |
| Set-Item WSMan:\localhost\Client\TrustedHosts 报"无法连接到目标" | 本机 WinRM 服务 Stopped(默认常是) | Start-Service WinRM |
| WinRM 报"必须使用 HTTPS 或添加到 TrustedHosts" | TrustedHosts 没写成功(同上) | 修好服务后重设 |
| 任务跑起来但日志一直是空的 | 远程 bat 里有 pause,无人会话永久等待 | 用 install-silent.bat(无 pause) |
| 远程会话查"默认打印机"返回空 | 正常,非交互式会话查不到 | 以 Get-Printer 为准 |
| 0x8009030e 指定的登录会话不存在 | 发起端不是域成员,拿不到 Kerberos 票据;或用了 IP 直连 | 让发起端加域,且始终用 FQDN,不要用 IP |
| Default authentication may be used with an IP address... | WinRM/DCOM 拒绝对裸 IP 做默认认证 | 改用 FQDN;或把 IP 加进 TrustedHosts;或用 HTTPS |
| The RPC server is unavailable(WMI 远程) | 目标机防火墙没放 DCOM/RPC 端口 | 放行 TCP 135 + 动态范围 49152-65535,并启用内置组「Windows Management Instrumentation (WMI)」 |
| schtasks.exe ... The request is not supported. | 远程 schtasks(/S)不支持 /RL HIGHEST | 不要用远程 schtasks 提权;改在目标机本地建任务,或用 GPO 启动脚本 |
| Invoke-CimMethod 报找不到参数 Credential | PS 5.1 的 CIM cmdlet 没有 -Credential | 凭据放在 New-CimSession -Credential 上,再把 session 传给 Invoke-CimMethod -CimSession |
| 脚本在目标机报"字符串缺少终止符" | UTF-8 无 BOM,PS 5.1 按 ANSI 读,中文注释错位 | 脚本存成 UTF-8 with BOM |
| Test-Path 对 \\主机\C$ 长时间不返回 | SMB 会话不健康时阻塞远超预期 | 用 Get-Content/Get-Item 包 try/catch,别用 Test-Path 探远路径 |
| -SharedQueue 报 Access is denied | 第二跳缺委派 | 加 -Auth CredSSP |
| 5986 报证书错误 | 自签证书 | 脚本已带 SkipCACheck/SkipCNCheck;仍失败先查 winrm enumerate winrm/config/listener |
脚本清单
本目录是全部脚本的唯一定稿位置,没有第二处副本。
| 脚本 | 作用 |
|---|---|
| install-printer-simple.ps1 | ★ 首选路径:WinRM 直连装(建会话 → 传驱动 → 4 条 cmdlet → 复核),型号 / IP 参数化 |
| find-printers.ps1 / .bat | ★ 本机路径入口:扫局域网发现打印机 + 取型号(打印端口指纹 + SNMP + HTTP)→ printers.csv |
| resolve-asset.ps1 / .bat | 姓名 / 计算机名 / MAC / IP → 目标电脑(读 assets.csv 资产清单),-InitTemplate 生成模板 |
| find-targets.ps1 / .bat | 定位:IP / 计算机名 / MAC / 网段扫描 → targets.csv |
| build-package.ps1 | 驱动目录 → 多架构离线包(x64/x86 + win7/win10 槽) |
| install-printer.ps1 | 随包在目标机执行:按 OS/架构选 INF → pnputil → 注册驱动 → 建端口 → 建队列 |
| printer-install.bat / printer-install-easy.bat | 本机安装的自提权启动器(双击跑,变量填在 bat 顶部) |
| cred-setup.ps1 / .bat | 弹 Windows 凭据框,DPAPI 加密落盘(不做明文转换) |
| probe.ps1 / .bat | 只读预检:连通 / DNS / 端口 / WinRM / 域成员 / 管理员 / 时钟偏差 |
| deploy.ps1 / .bat | 单台远程部署(Kerberos/NTLM/CredSSP 自动回退) |
| deploy-all.ps1 / .bat | 批量部署 + 逐台日志 + 汇总 CSV |
| ms-catalog.py | 搜 Microsoft Update Catalog 拿官方驱动直链 |
| pack-skill.ps1 | 把整个技能导出成可分发的目录/zip(发同事、拷 U 盘用) |
| selfrun/ | 备选通道(目标机没开 WinRM / 走 GPO·SCCM / 完全离线时用),见下 |
输出位置约定:日志与凭据一律写到当前工作目录;若当前目录恰好是技能目录(双击 bat 的常见情形),自动改到 %USERPROFILE%\PrinterDeploy。技能目录只放代码,不落任何运行产物(deploy-log.txt / target-install-log.txt / install-log.txt / cred.xml 都不该出现在这里)。
备选通道:self-run(本地账号 / 无 WinRM)
域账号走 WinRM 直接装即可。只有本地账号被 UAC 削令牌、或目标机没开 WinRM 时才需要它
(把脚本推过去,目标机自己跑完)。脚本在 scripts/selfrun/:
| 脚本 | 作用 |
|---|---|
| build-selfrun-package.ps1 | 驱动 + 脚本 + config.json 打成一个可推送载荷 |
| push-selfrun.ps1 | 推送器,三通道 smb / winrm / gpo |
| client-run.ps1 | 客户端自运行:自提权 + 幂等 + 写 result.json 判定 |
| push-and-verify.ps1 | 端到端串联(宿主 → DC → 目标 → 回读判定),需按拓扑改主机名 |
| reset-target-clean.ps1 | 把目标机还原到"零"状态,用于验证"真能从零装" |
三条通道:gpo(机器启动脚本,SYSTEM 完整权限,域里最干净)、smb(拷 + WMI 触发,不需 WinRM)、
winrm(远程建计划任务)。判定靠 result.json,不要靠正则匹配日志。
三个必要条件:① 目标机 5985 可达 ② 本机 WinRM 服务 Running ③ 本机 TrustedHosts 含目标 IP(工作组)。
完整流程、WMI 触发写法、清残留手法见 references/self-run.md。
实测记录(摘要)
- 20 品牌驱动直链全部打通,其中 12 家在域 VM 跑完完整安装闭环(oem6–oem17)——配方见
references/driver-direct-links.md - 域实验室(DC01 → PC01,
corp.test):FQDN + Kerberos PASS;走 IP 必 FAIL(0x8009030e);端到端 8 秒装完 - 入口路由发现脚本(本机 192.168.0.0/24):ping 扫会漏掉禁 ICMP 的 HP M1213nf,改打印端口扫后命中且型号识别正确
完整历史与踩坑清单见 references/testing-log.md。
微信扫一扫