PowerShell: Cancel all print jobs

Here’s a quick PowerShell script I put together to delete all print jobs from our Windows Server 2008 R2 print server. It’s run overnight as a scheduled task. We do this because sometimes our print accounting software doesn’t clear out old jobs if users haven’t released them at the printer.

EDIT: January 2015

Just reviewing my old posts. Here’s how I’d do this nowadays:

Get-WmiObject Win32_Printer -Filter "(Local = $true) and (Shared = $true)" | ForEach-Object {$_.CancelAllJobs()}

It’s better practice to do the filtering in WMI earlier, rather than retrieve more printers and filter them out in PowerShell afterwards.

Here’s the old code

$printers = Get-WmiObject Win32_Printer

if ($printers.Count -eq 0) {
    Write-Host -ForegroundColor red "No Printers Found"
    exit
}

foreach ($printer in $printers) {
    
    if ($printer.Local -and $printer.Shared)
    {
        Write-Host -ForegroundColor Green "Cancelling all jobs on: $($printer.Name)"
        $printer.CancelAllJobs()
        
    }
}

It will only clear print jobs on local printers that are shared out. There’s some more info about the Win32_Printer class and the CancelAllJobs method on MSDN.

Note that I haven’t included any error-checking in this script at all, so run it manually first to see if it will work. As always, run at your own risk.

To schedule it, simply create a new scheduled task:

    1. Run with highest privileges
    2. Run whether user is logged on or not
    3. Do not store password
    4. Action: Start a program: C:WindowsSystem32WindowsPowerShellv1.0powershell.exe
    5. Arguments: -File “C:path-to-script-filename-of-script-file.ps1”

clearqueues-generaltab

clearqueues-action

4 thoughts on “PowerShell: Cancel all print jobs

  1. Your script can be more efficient by using a WMI filter. Now, you are getting every printer and later going through to take an action on printers that are local and shared. The best practice is to filter as early in your expression as you can. Here’s a one line alternative.

    get-wmiobject win32_printer -filter “Local=’True’AND shared=’True'” | foreach {
    Write-Host “Cancelling all jobs on $($_.Name)” -ForegroundColor Green
    $_.CancelAllJobs()
    }

    The tricky thing is that WMI filters use the legacy operators, not PowerShell operators.

    Like

  2. Excellent. Goes to show why you’re an MVP… 😉

    This is my second attempt at a PS script that does anything useful. I’m still getting my head around the way things operate in PowerShell. All of the different operators, the way to refer to objects inside a loop, etc.

    I’ll certainly use the WMI filters if I do any similar scripting in the future. For now though, I’m happy to leave it as-is. I don’t need to worry too much about the efficiency of the script. It would be another story if I was running it on a server with 1000 printers.

    Thanks for leaving feedback.

    Daniel

    Like

  3. I just tested your one-line edit on a Windows 7 PC and it did not delete a single print job. I created a number of print jobs to various printers on the test PC, used prnjobs.vbs -l to list all the print jobs to verify they were still sitting in various queues and waiting.

    It did not work. I removed the filter and then it deleted all but one print job – but that print job did show status “Job is being deleted”.

    Any reason for the difference? Maybe because it’s Windows 7 versus Windows Server 2008?

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s