如何用Get-WMIObject实现打印机暂停?PowerShell技术求助
实现打印机暂停/恢复打印的PowerShell函数
需求
创建PowerShell函数,实现与打印机队列对话框“Printer”菜单中Pause Printing(暂停打印)完全一致的功能:暂停后新打印任务进入队列,恢复后继续执行打印。
尝试过程及问题
参考代码及执行情况
找到的参考代码:
Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue | Select Name, JobsSpooling, Jobs|where {$_.jobs -gt 0} (gwmi win32_printer -filter "name='printer_name'").pause() (gwmi win32_printer -filter "name='printer_name'").resume()
- 第一行命令执行正常,输出:
Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue | Select Name, JobsSpooling, Jobs Name JobsSpooling Jobs ---- ------------ ---- Xerox 0 2 _Total 0 2
遇到的错误
- 运行
(gwmi win32_printer -filter "name='printer_name'").pause()时报错:gwmi: The term 'gwmi' is not recognized as a name of a cmdlet, function, script file, - 改用
(Get-WmiObject win32_printer -filter "name='printer_name'").pause()时报错:InvalidOperation: You cannot call a method on a null-valued expression. - 尝试从性能对象调用方法:
报错:$obj = Get-WMIObject Win32_PerfFormattedData_Spooler_PrintQueue | Select Name, JobsSpooling, Jobs $obj.pause()InvalidOperation: Method invocation failed because [Selected.System.Management.Automation.PSCustomObject] does not contain a method named 'pause'.
补充信息
打印机名称为xerox,使用Get-PrintJob -PrinterName xerox可正常查询到打印任务:
Get-PrintJob -PrinterName xerox Id ComputerName PrinterName DocumentName SubmittedTime JobStatus -- ------------ ----------- ------------ ------------- --------- 26 Xerox xxxxx.txt - Notepad 28/03/2024 17:22:15 Normal 27 Xerox xxxxx.txt - Notepad 28/03/2024 17:22:19 Normal
不确定是否需要使用打印机的技术名称,也不清楚如何获取。
可行解决方案
方法1:使用CIM命令替代WMI(推荐,PowerShell 5.1+支持)
WMI系列cmdlet已被CIM替代,Get-CimInstance能准确获取打印机对象并调用方法:
# 暂停指定打印机 Get-CimInstance Win32_Printer -Filter "Name='Xerox'" | Invoke-CimMethod -MethodName Pause # 恢复指定打印机 Get-CimInstance Win32_Printer -Filter "Name='Xerox'" | Invoke-CimMethod -MethodName Resume
如果打印机名称包含空格或特殊字符,需先确认系统中打印机的准确名称:
Get-CimInstance Win32_Printer | Select-Object Name, PrinterStatus
方法2:封装为可复用函数
将功能封装成函数,支持指定打印机名称并自动切换暂停/恢复状态:
function Toggle-PrinterPause { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [string]$PrinterName ) $printer = Get-CimInstance Win32_Printer -Filter "Name='$PrinterName'" if (-not $printer) { Write-Error "找不到打印机:$PrinterName" return } if ($printer.PrinterStatus -eq 3) { # 3代表打印机正常运行(未暂停) $printer | Invoke-CimMethod -MethodName Pause Write-Host "已暂停打印机:$PrinterName" } elseif ($printer.PrinterStatus -eq 4) { # 4代表打印机已暂停 $printer | Invoke-CimMethod -MethodName Resume Write-Host "已恢复打印机:$PrinterName" } else { Write-Host "打印机当前状态代码:$($printer.PrinterStatus)" } }
使用示例:
# 切换Xerox打印机的暂停/恢复状态 Toggle-PrinterPause -PrinterName "Xerox"
失败原因分析
gwmi是Get-WmiObject的别名,在PowerShell Core中已被移除,因此报错找不到命令;Get-WmiObject win32_printer返回null是因为Filter中的打印机名称与系统实际名称不匹配(需注意大小写或特殊字符);Win32_PerfFormattedData_Spooler_PrintQueue是性能计数器对象,并非打印机对象,本身没有pause()方法,因此调用失败。
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

