Windows Server 2016打印管理控制台无法获取打印机序列号求助
无法从Windows Server 2016打印队列获取打印机序列号的问题
需要从Windows Server 2016打印管理控制台及同类型服务器中获取打印机IP、打印队列名称和序列号,但仅能获取到IP(实际为端口名称)和打印队列名称,序列号始终为空。已尝试以下两个PowerShell脚本,但问题未解决:
单服务器获取脚本
Import-Module PrintManagement $printers = Get-PrintQueue foreach ($printer in $printers) { $data = @{ Name = $printer.Name IP = $printer.PortName Serial = $printer.SerialNumber Port = $printer.PortName } New-Object -TypeName PSObject -Property $data } | Export-Csv -Path "C:\printers.csv" -NoTypeInformation
该脚本导入Print Management模块,通过Get-PrintQueue获取所有打印机,提取队列名称、端口名(误作为IP)、序列号和端口信息并导出到CSV,但SerialNumber属性始终为空。
多服务器批量获取脚本
$servers = Get-Content -Path "C:\serverlist.txt" foreach ($server in $servers) { $printers = Get-PrintQueue -ComputerName $server foreach ($printer in $printers) { $data = @{ Server = $server Name = $printer.Name IP = $printer.PortName Serial = $printer.SerialNumber Port = $printer.PortName } New-Object -TypeName PSObject -Property $data } } | Export-Csv -Path "C:\printers.csv" -NoTypeInformation
该脚本读取服务器列表批量查询,但同样无法获取序列号,且仍将端口名当作IP。
问题原因
Get-PrintQueue的SerialNumber属性值完全依赖于打印机驱动是否向打印服务器上报该信息,或者打印服务器是否通过SNMP成功读取打印机硬件数据。大多数情况下为空的原因包括:
- 打印机驱动未实现序列号上报功能
- 打印服务器未启用SNMP服务,或SNMP配置与打印机不匹配(如社区字符串不一致)
- 打印机本身不支持通过打印协议暴露序列号
解决方案:改进后的PowerShell脚本
单服务器版本(修正IP获取+多渠道获取序列号)
Import-Module PrintManagement # 预加载打印机端口信息以获取真实IP $allPorts = Get-PrinterPort $output = @() foreach ($printer in Get-PrintQueue) { # 从端口信息中提取真实IP(仅RAW类型端口有HostAddress) $targetPort = $allPorts | Where-Object { $_.Name -eq $printer.PortName } $printerIP = if ($targetPort.PortType -eq "RAW") { $targetPort.HostAddress } else { $printer.PortName } # 尝试从WMI获取序列号 $wmiPrinter = Get-CimInstance Win32_Printer -Filter "Name='$($printer.Name.Replace("'", "''"))'" $serialNumber = $wmiPrinter.SerialNumber # WMI无结果时,尝试通过SNMP查询(需安装SnmpPS模块,且打印机允许SNMP访问) if (-not $serialNumber) { try { if (-not (Get-Module -Name SnmpPS -ListAvailable)) { Install-Module SnmpPS -Force -Scope CurrentUser } Import-Module SnmpPS # OID对应打印机序列号(大部分厂商通用) $snmpData = Get-SnmpData -IP $printerIP -Oid "1.3.6.1.2.1.43.5.1.1.17.1" -CommunityString "public" $serialNumber = $snmpData.Value } catch { $serialNumber = "无法获取" } } $output += [PSCustomObject]@{ 打印队列名称 = $printer.Name 打印机IP = $printerIP 序列号 = $serialNumber 端口名称 = $printer.PortName } } $output | Export-Csv -Path "C:\printers.csv" -NoTypeInformation -Encoding UTF8
多服务器批量版本
$servers = Get-Content -Path "C:\serverlist.txt" $output = @() foreach ($server in $servers) { try { # 远程获取打印队列和端口信息 $printers = Get-PrintQueue -ComputerName $server -ErrorAction Stop $allPorts = Get-PrinterPort -ComputerName $server -ErrorAction Stop foreach ($printer in $printers) { $targetPort = $allPorts | Where-Object { $_.Name -eq $printer.PortName } $printerIP = if ($targetPort.PortType -eq "RAW") { $targetPort.HostAddress } else { $printer.PortName } # 远程WMI查询序列号 $wmiPrinter = Get-CimInstance Win32_Printer -ComputerName $server -Filter "Name='$($printer.Name.Replace("'", "''"))'" -ErrorAction SilentlyContinue $serialNumber = $wmiPrinter.SerialNumber # WMI无结果时,本地发起SNMP查询(需打印机IP可达) if (-not $serialNumber) { try { if (-not (Get-Module -Name SnmpPS -ListAvailable)) { Install-Module SnmpPS -Force -Scope CurrentUser } Import-Module SnmpPS $snmpData = Get-SnmpData -IP $printerIP -Oid "1.3.6.1.2.1.43.5.1.1.17.1" -CommunityString "public" $serialNumber = $snmpData.Value } catch { $serialNumber = "无法获取" } } $output += [PSCustomObject]@{ 服务器名称 = $server 打印队列名称 = $printer.Name 打印机IP = $printerIP 序列号 = $serialNumber 端口名称 = $printer.PortName } } } catch { Write-Warning "服务器 $server 访问失败: $_" } } $output | Export-Csv -Path "C:\printers.csv" -NoTypeInformation -Encoding UTF8
注意事项
- 运行脚本的账户需具备目标服务器的打印管理权限和WMI远程访问权限
- 使用SNMP查询前,需确保:
- 打印机启用了SNMP服务,且社区字符串与脚本中的
public一致(若不同需修改) - 本地已安装
SnmpPS模块(可通过Install-Module SnmpPS安装)
- 打印机启用了SNMP服务,且社区字符串与脚本中的
- 部分老旧打印机或特殊型号可能不支持SNMP或不暴露序列号,此类设备只能标记为"无法获取"
内容的提问来源于stack exchange,提问作者djehuti
相关产品推荐
相关产品推荐

