Summary: Learn how to use Windows PowerShell to test remote printers.
Hey, Scripting Guy! I don’t know what it is, but for some reason printing still seems to be a pain. I mean, we have been using the network for a long time, and something as basic as printing still seems to be a problem. Whatever happened to the paperless office of the future? All we do is kill trees faster by using high-speed printers to print massive amounts of useless junk that no one reads.
Anyway, for some reason, about half of our Help Desk calls are related to print issues. To be sure, some of it is user training issues—people trying to select the wrong feature for the wrong printer. But in all honesty, not all of the print problems are user related. For example, sometimes the print spooler seems to die, and we need to restart it. My Help Desk techs can open Computer management to stop and restart the spooler service, but I would like to do this via a script. Can you help?
—RM
Hello RM,
Microsoft Scripting Guy, Ed Wilson, is here. We continue to get lots of rain here in Charlotte, North Carolina. Lots and lots of rain. The solar heaters for our pool are not doing much good these days. Oh well, maybe the sun will come out tomorrow.
The print management module
RM, you did not say if you are using Windows 8, so I am going to assume that you are. In Windows 8 (and in Surface RT, Surface Pro, and Windows Server 2012), there is a print management module called PrintManagement. It exposes the following commands:
PS C:\> Get-Command -Module PrintManagement
CommandType Name ModuleName
----------- ---- ----------
Function Add-Printer PrintManagement
Function Add-PrinterDriver PrintManagement
Function Add-PrinterPort PrintManagement
Function Get-PrintConfiguration PrintManagement
Function Get-Printer PrintManagement
Function Get-PrinterDriver PrintManagement
Function Get-PrinterPort PrintManagement
Function Get-PrinterProperty PrintManagement
Function Get-PrintJob PrintManagement
Function Remove-Printer PrintManagement
Function Remove-PrinterDriver PrintManagement
Function Remove-PrinterPort PrintManagement
Function Remove-PrintJob PrintManagement
Function Rename-Printer PrintManagement
Function Restart-PrintJob PrintManagement
Function Resume-PrintJob PrintManagement
Function Set-PrintConfiguration PrintManagement
Function Set-Printer PrintManagement
Function Set-PrinterProperty PrintManagement
Function Suspend-PrintJob PrintManagement
Inspecting a network printer connection
From a client workstation (one defined with a network printer), I can use the Get-Printer function. This function returns detailed information about every printer that is defined on the local system. This includes what I consider to be real printers and what I consider to be virtual printers. In the system that follows, only one real printer is defined, and it happens to not be able to connect to the server.
PS C:\> Get-Printer | select printerstatus, name, computername
PrinterStatus name computername
------------- ---- ------------
Normal Snagit 11
Normal Send To OneNote 2013
Normal Microsoft XPS Document W...
Normal Fax
ServerOffline \\dc1.iammred.net\HP Las... dc1.iammred.net
Because the server is reported as offline, there are a couple of possibilities. It may be that the server is actually down, or it may be that the spooler service is not responding. If the spooler is hung, I can restart the service. If the server is down, or not responding to remote queries, I need to restart the server.
This is exactly what the RestartSpoolerService.ps1 script does. If the server is up and responding to a ping, but the PrinterStatus is not normal, the script restarts the spooler service. This script does not use credentials, but it would be easy to modify it to do so by first soliciting credentials via Get-Credential and storing the returned credential object in a variable. Then supply the credential object to the Invoke-Command cmdlet. This script is shown here:
get-printer |
select printerstatus, name, computername |
Foreach {
If ($_.PrinterStatus -ne 'normal')
{
if(Test-Connection -ComputerName $_.ComputerName -Quiet)
{Invoke-Command -ComputerName $_.ComputerName -ScriptBlock {Restart-Service -Name Spooler} } }}
RM, that is all there is to using Windows PowerShell to test printer servers. Printer Week will continue tomorrow when I will talk about creating printer ports.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy