1

On our primary windows 2003 print server we share about 500 printers. We typically have about 50 stuck print jobs. Although far from the end of the world it bugs the hell out of me and I tend to end up spending 30 odd mins a week searching for and deleting stuck jobs.

What I would really like is a script to delete all print jobs on all printers older than 24 hours.

Coming from a UNIX background I find windows scripting pretty confusing. Any advice on how I can get started with this task would be appreciated. Any complete solutions would be amazing. ;)

Cheers,

Mat.

4 Answers 4

6

This should be fairly simple to do in Powershell. You will find powershell a little more to your liking coming from *nix. You will however be working with WMI, which is truely a blessing and a curse.

Some example code that does what you want (NOT TESTED):

$strComputer = "."

$PrintJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" -computername $strComputer | Where-Object { $_.StartTime -lt $($(Get-Date).addDays(-1)) }

foreach ($job in $PrintJobs) {
    Write-Host "Canceling job $($job.JobId)"
    $job.Delete
}

Basically you will just need to get all objects from WMI where the Start Time is less than now - 24 hours.

4
  • Brilliant. Am I right in thinking that the printjob object will also have control functions, something like: $objItem.DeleteJob? I will just have to look at how time is handled. Thanks, I would mark you up, but not enough points yet...
    – Matthew
    May 28, 2009 at 21:00
  • Edited the script to hopefully give the exact script you need. May 28, 2009 at 21:01
  • ok, i get it. will try it in the morning. I like the way time is handled no need to count in seconds. addDays(-1) is pretty funny though ;) thanks again. Mat.
    – Matthew
    May 28, 2009 at 21:14
  • Powershell does a pretty good job of making things fairly easy. Glad to help. May 29, 2009 at 0:03
2

This could be your strategy. Stop the spooler service, delete all old files and restart the service.

Write this script code in a text file and name it "DeleteOldQueuedFile.vbs":

Dim Fso, Directory, Modified, Files
Set Fso = CreateObject("Scripting.FileSystemObject")
Set Directory = Fso.GetFolder("%systemroot%\system32\spool\printers")
Set Files = Directory.Files

For Each Modified in Files  
   If DateDiff("D", Modified.DateLastModified, Now) >= 1 Then Modified.Delete
Next

Write a batch file which you could schedule as a nightly job:

net stop spooler
DeleteOldQueuedFile.vbs
net start spooler
1
  • Thanks, It is interesting to see the difference in strategies. It is kind of strange, I am more familiar with working with the file system, as your script does, but the first script has given me a insight into the potential of WMI which frankly I was unaware of. Thanks again. It is good to see that not only is there more than one way to achieve my goal but also that I can treat the windows print spool as just a bunch of files. I take it that the print spooler locks all files in the spool directory - hence why you stop the service. That is potentialy a lot of file handles...
    – Matthew
    May 28, 2009 at 21:44
1

If you go into the windows 2003 resource kit, there is a tool designed to do this called Cleanspl.exe.

Resource Kit: mircosoft url /downloads/details.aspx?FamilyID=9D467A69-57FF-4AE7-96EE-B18C4790CFFD&displaylang=en

or you can script it:

echo Printers - Shutting down the print spooler
net stop "pcounter printer control"
net stop "print spooler"
echo Printers - Deleting print queues
del c:\WINDOWS\system32\spool\PRINTERS\*.* /q

net start "print spooler"
net start "pcounter printer control"
echo Printers - Print spooler Started
0

Not sure if the accepted answer was working at the time but on Server 2012 R2 and 2016 it would not work anymore.

The property is now TimeSubmitted and it cannot be compared to a DateTime without converting from a WMI Timeobject. Also the Delete method cannot be called like in the accepted answer because of overloads. So an updated Version would be:

$printJobs = get-wmiobject -class "Win32_PrintJob" -namespace "root\CIMV2" | Where-Object {[System.Management.ManagementDateTimeConverter]::ToDateTime($_.TimeSubmitted) -lt (Get-Date).addDays(-1)}    
foreach ($job in $printJobs) {
    $job.Delete()
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.