← Back to skills
extension
Category: Productivity & OfficeAPI key requirement unconfirmed

network-printer-install

一条命令搞定 Windows 网络打印机安装与批量部署(Win10/11,x86/x64):先扫局域网发现打印机、确认型号、经确认后给本机装,也可远程给局域网 / 域内电脑或整网段批量装。按目标标识(IP / 计算机名 / MAC / 姓名)自动路由,远程前先确认工作组或域。内置 20 大品牌驱动直链,pnputil + Add-PrinterDriver + TCP/IP 端口 + Add-Printer 安装,支持离线预装;远程支持 WinRM、CredSSP、GPO 通道,按目标 OS 与 32/64 位自动选驱动。适用于装打印机 / 装驱动 / 添加或重装网络打印机 / 给同事或域内电脑加打印机 / 批量部署。不装厂商套件与附加软件,发测试页前先征得确认。 One-command Windows network printer install & mass deploy (Win10/11, x86/x64): scan LAN, confirm model, install locally after confirmation, or remote/batch to LAN/domain PCs or a subnet. Routes by target ID (IP/hostname/MAC/username); confirms workgroup vs domain before remote ops. Direct links for 20 printer brands; installs via pnputil + Add-PrinterDriver + TCP/IP port + Add-Printer; supports offline pre-install; remote via WinRM, CredSSP, GPO; auto driver selection by OS & 32/64-bit. For installing/adding/reinstalling printers, adding printers for colleagues/domain PCs, or mass deployment. No vendor suites or bloatware; confirm before test page.

personAuthor: zhh312zhhhubModelScope

打印机安装与部署(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 页面 → HTTP Server 头;都取不到就标 (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.com 403,但 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 x 0.82 s vs 跑安装器 /s 69.3 s + 弹窗)。 绝不要运行厂商安装器(真需要时必须在 VM 里做)
  • 按内容找 INF,别按扩展名:grep -rl -a "Class=Printer" <解包目录>; 认准 Class = Printer(同包里 Class = USB 的是配套工具);驱动名在 [Strings] 段

装不上时先查这三个(都不是包坏了):

  1. cat 名不对 → 必须按 INF 的 CatalogFile= 取(Riso 的 INF 叫 RISODRV.INF,cat 却是 RC20.CAT)
  2. 驱动在 cab 里 → [SourceDisksNames] 写 PRINTER.cab 时,先 expand -R -F:* PRINTER.cab <inf目录>
  3. 签名证书未被信任 → 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。