PowerShell遍历获取打印机IP脚本跨服务器运行异常求助
脚本失效根因
原脚本迁移后无法运行、覆盖场景不全的核心问题如下:
- 未提前初始化
$results数组,不同PowerShell运行环境下会直接抛出"变量未定义"终止错误 - 仅通过PortName做DNS解析的逻辑存在缺陷:标准TCP/IP打印端口如果直接配置IP地址,原逻辑会把IP当主机名送解析,大概率返回解析失败,拿不到正确结果
- 加了
-NoClobber参数,如果输出路径下已经存在同名csv文件,脚本会直接终止,迁移服务器后如果残留历史文件就会卡住 - 导出临时csv后用纯文本方式读取、替换双引号的写法兼容性差,遇到不同编码的csv文件会读入乱码,导致后续解析全失败
- 没有做异常捕获,单条记录解析失败就会中断整个执行流程,无法拿到完整清单
优化方案
直接读取打印端口配置信息,不需要依赖DNS解析也能拿到打印机配置的连接地址,兼容配置主机名、直接配置静态IP两种场景,修复所有兼容性问题的脚本如下:
$results = @() $outputPath = "C:\scripts\printerips.csv" # 自动创建输出目录 if (-not (Test-Path "C:\scripts")) { New-Item -Path "C:\scripts" -ItemType Directory -Force | Out-Null } # 遍历所有打印机关联端口信息 Get-Printer | ForEach-Object { $currentPrinter = $_ $currentPort = Get-PrinterPort -Name $currentPrinter.PortName -ErrorAction SilentlyContinue # 优先取端口内存储的连接地址,不存在则回退用端口名 $connectAddress = if ($currentPort.PrinterHostAddress) { $currentPort.PrinterHostAddress } else { $currentPrinter.PortName } # 尝试DNS解析,本身是IP则直接保留,解析失败则标注原配置地址 $resolvedIP = $connectAddress if ($connectAddress -notmatch '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') { try { $dnsRes = Resolve-DnsName -Name $connectAddress -ErrorAction Stop | Where-Object IPAddress $resolvedIP = ($dnsRes.IPAddress | Where-Object { $_ -notmatch ':' }) -join ';' } catch { $resolvedIP = "解析失败,原配置地址:$connectAddress" } } # 组装结果条目 $results += [PSCustomObject]@{ 打印机名称 = $currentPrinter.Name 端口名称 = $currentPrinter.PortName 端口配置地址 = $connectAddress 解析后IP = $resolvedIP 驱动名称 = $currentPrinter.DriverName 是否共享 = $currentPrinter.Shared } } # 导出为UTF8编码的CSV,自动覆盖旧文件 $results | Export-Csv -Path $outputPath -NoTypeInformation -Encoding UTF8
使用说明
- 脚本适配PowerShell 5.1及以上版本,兼容Windows Server 2012R2到2022所有版本的打印服务角色
- 不需要生成临时中间文件,直接读取打印服务器的端口配置,直接配置静态IP的打印机不需要走DNS解析就能返回正确IP
- 单台打印机解析失败不会中断整体执行,失败条目会在结果中明确标注
- 导出CSV默认用UTF8编码,直接用Excel打开不会出现乱码
- 结果额外包含驱动、共享状态字段,可直接用于打印资产盘点
内容的提问来源于stack exchange,提问作者Rich
相关产品推荐
相关产品推荐

