奇怪的打印问题:Windows 共享打印机可通过主机名访问/看到,但不能通过 IP 地址访问/看到

奇怪的打印问题:Windows 共享打印机可通过主机名访问/看到,但不能通过 IP 地址访问/看到

自大约 8-10 个月前以来,我们一直面临奇怪的打印机问题,本月达到顶峰,出现大量错误,令公司大部分人都参与其中,这也让我们确定了核心问题:在某些机器上(~7-8%)有时在重新启动后,打印后台处理程序会发生一些事情,导致打印机无法通过 IP 地址进行宣传/可用,只能通过主机名进行宣传/可用。

具体来说,该问题表现在三个方面:

  • 从 Linux 服务器发送打印时,服务器将收到错误,并且事件日志将出现以下错误“自动行式打印机守护程序 (LPD) 服务拒绝来自 %LINUXSERVERIP% 的打印机 \%WindowsIP%%PrinterName% 的打印作业,因为指定的打印机不存在于此计算机上。”

  • 当尝试通过 Windows 资源管理器中的 \%WindowsIP%\ 转到 Windows 计算机来映射打印机时,打印机将可见,但尝试添加它将导致错误“操作无法完成(错误 0x00000709)。”这通常与 KBKB5006670 有关,但我们的计算机上没有安装该程序,上述错误的第一个实例发生在 2021 年 12 月/2022 年 1 月,远早于该补丁发布之前

  • 运行 powershell 命令 Get-Printer -Computername %WindowsIP%。如果使用计算机的主机名运行该命令,则结果是正确的(共享打印机的列表);如果使用计算机的 IP 地址运行该命令,则会引发以下错误:

      + CategoryInfo          : NotSpecified: (MSFT_Printer:ROOT/StandardCimv2/MSFT_Printer) [Get-Printer], CimException
      + FullyQualifiedErrorId : HRESULT 0x8007007b,Get-Printer
    

最烦人的是:如果您重新启动 Spooler 服务,问题就会完全消失,直到下次重新启动......

通过 Google 进行搜索并没有获得太多结果,只有一条消息没有得到答复:https://hardforum.com/threads/weird-network-printing-problem.1635293/

所有东西都有一个 XKCD,不是吗?https://xkcd.com/979/

使用 Procmon、Wireshark、Process Explorer、WinDbg 和 xbootmgr 进行了额外分析,结果如下:

  • Procmon:

    • 从另一台计算机执行 Get-Printer %WindowsIP% 期间对 spoolsv.exe 的分析显示,除了网络通信之外没有其他操作
    • 通过 Windows 资源管理器添加共享打印机时对 spoolsv.exe 的分析显示了网络连接和一些 RegQueryKey,用于 HKU%SIDOFREMOTEACCOUNT% 和 HKU.DEFAULT\Printers\Connections,,%WINDOWSIP%,%PRINTERNAME%,结果为“NAME NOT FOUND”,但没有其他结果
    • 通过启用启动日志功能尝试在启动过程中分析 spoolsv.exe,成功了,但由于启用该选项后启动时不会出现问题,因此毫无用处
    • 已经尝试通过堆栈摘要功能进行额外分析,以从 spoolsv.exe 向下追踪堆栈,但在工作和非工作 procmon 转储之间唯一的共同线程中值得注意的差异是在工作服务的转储上存在一个名为 EatAuthInfoFromPacket 的附加分支。
  • Wireshark:

    • 从远程计算机执行 Get-Printer 时对流量进行表面分析,显示 winspool_AsyncEnumPrinters 请求和 winspool_AsyncEnumPrinters 响应使用协议 IREMOTEWINSPOOL,但没有其他信息,并且存根数据似乎已加密,因此我无法从中获取更多信息
  • 进程探索器

    • 已经对 spoolsv.exe 进程及其线程和堆栈进行了初步分析,唯一有趣的一点是,当 spoolsv.exe 进程出现故障时,其字符串中有 \machinehostname 和 \machinehostname.domain.com,而当没有出现故障时,则没有任何内容。但我不得不承认,我对 Windows Internals 的了解不足以完全理解它。不过,OpenAI 一直在帮助解释!
  • 调试

    • 调试器已附加到 spoolsv.exe 进程,并使用远程计算机的 Get-Printer 和尝试通过 Windows 资源管理器映射打印机进行了测试,但在这两种情况下,执行期间均未显示任何调试消息。此外,我从 Process Explorer 创建了一个进程转储并将其提供给 WindDbg 以运行 !analyze 命令,但它只返回了一个断点,没有实际错误。与以前一样,我是这个工具的新手,所以如果您有任何建议,我很乐意采纳!
  • 启动管理器

    • xbootmgr -trace boot -traceflags dispatcher+latency -stackwalk readythread+threadcreate+profile+cswitch 已运行以在启动期间调试服务,但与 Procmon 相同,当机器重新启动并进行此跟踪时,问题不会出现,因此输出相当无用

这就是总结。我有点迷茫,Google 和 OpenAI 似乎都不知道这里发生了什么,所以如果您能提供关于此问题的其他故障排除的见解,或者如果您以前遇到过这个问题,我非常感激您能提供解决方案。

答案1

如果其他人有这个问题,以下是来自微软的答案:

原因(背景故事)是多层次的。这是基本的概述。服务启动 Windows 中已进行了许多更改,以缩短启动时的服务启动时间。这使得某些服务可以比过去更早启动。如果服务具有网络依赖性并且在 DAD 完成且接口和 IP 可供使用之前超时,则服务可能无法启动。硬件计算机硬件的改进是一个主要因素。所有现代处理器都有多个核心/线程,允许并行处理操作系统任务。处理器的速度也大幅提高。这些变化使 Windows 等操作系统能够更快地并行执行多个任务,从而大幅缩短服务启动时间。可用 RAM 的数量迅速增加。这意味着更少的磁盘分页,也缩短了启动时间。最显著的改进是存储。存储现在主要基于闪存(SSD),并且通常使用高速 NVMe 互连。如今,即使是存储后端,如 NAS 或 SAN,也都是基于闪存的。旧式旋转磁盘 (HDD) 和 NVMe SSD 之间的 IO、延迟和吞吐量改进大约快了 150 多倍。这一变化发生在不到 10 年的时间内。结果在改进之前,服务在启动时启动需要两位数秒。当 DAD 首次添加到 Windows 时,可能需要几分钟才能让所有服务准备就绪。无需补偿 DAD,因此大多数代码只是忽略了 IP 地址状态。服务启动行为的共同变化和最近的硬件改进使服务启动只需个位数秒。根据 Windows 行为和 RFC 要求,早在 IP 地址准备好使用之前。简单地将 IPv4 的 DAD 传输默认值更改为 1 并不是一个长期的解决方案。随着硬件和服务的不断改进,即使是一秒钟的延迟也足以导致服务在启​​动时失败。遇到问题的服务必须更改为在尝试网络连接或绑定到 IP 之前监视 IP 地址状态。已知问题 这是 CSS 可能遇到的与 DAD 和服务启动相关的常见问题的列表。 使用域帐户的服务无法启动 使用域帐户的服务特别依赖于网络是否已准备就绪并可访问以执行域控制器的身份验证。 未经身份验证,服务将无法启动。 当服务启动和超时速度快于网络准备就绪所需的时间时(这通常与等待 DAD 完成有关),服务将无法启动。 这在 SQL Server 中很常见,但它可能发生在任何使用域帐户登录的服务上。

可以通过减少 DAD 传输次数、禁用 DAD 或将服务上的“恢复”选项设置为重新启动来解决此问题。请参阅解决方法:

服务启动时无法绑定到 IP 地址 当服务尝试将服务绑定到 IP 地址但在网络准备就绪之前超时或出错时,就会发生此问题。同样,这通常是由于 DAD 等待而发生的。网络堆栈无法将服务绑定到非首选状态的 IP 地址。此问题经常出现在后台处理程序(打印服务器)服务中。可以通过禁用 DAD 或将服务启动设置为“自动(延迟启动)”来解决此类问题。当服务没有失败/停止时,其他解决方法可能不起作用,它只是继续运行而没有将服务绑定到 IP 地址。重启时 IPv6 地址从 DNS 服务器中消失 DHCP 客户端可能会在 IPv6 DAD 完成之前请求 DNS 注册。发生这种情况时,DNS 客户端在动态 DNS 更新期间会从 DNS 服务器中删除/消失 IPv6 地址。

我希望这对你有所帮助,同时我想提请你注意,目前还没有找到最终的解决方案。

相关内容