Hey, Scripting Guy! Question

Hey, Scripting Guy! How can I disable the Keep Printed Documents attribute on a printer?

-- JJ

SpacerHey, Scripting Guy! AnswerScript Center

Hey, JJ. You didn’t mention which operating system you’re trying to do this on, but we hope it’s a Windows XP or Windows Servers 2003 computer. Why? Well, on a Windows XP or Windows Server 2003 machine, this is easy; on any other version of Windows it’s a bit harder. How much harder? Well, to tell you the truth, it’s downright impossible.

Which definitely makes the task a bit harder to carry out.

Yes, we know: that isn’t fair. But such is life. With Windows XP, the WMI class Win32_Printer was upgraded to include a new read/write property: KeepPrintedJobs. As you might have guessed, we can simply toggle this property value back-and-forth to keep (or not keep) printer jobs for a specified printer. Unfortunately, this property does not exist on any version of Windows prior to Windows XP. With, say, Windows 2000, we can use a script to tell whether or not this attribute is enabled for a printer, but we can’t actually change the value.

Note. Sadly, ADSI - which often provides a handy workaround for printer management in Windows 2000 - is of little use to us here. There is a new ADSI attribute for configuring the Keep Printed Documents property but it won’t do you any good on a Windows 2000 computer, either.

Assuming that you are using Windows XP or Windows Server 2003, however, then you can disable the Keep Printed Documents property by using a script like this:

strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where DeviceID = 'ArtDepartmentPrinter'")

For Each objPrinter in colPrinters
    objPrinter.KeepPrintedJobs = False
    objPrinter.Put_
Next

We know: it seems really unfair that you can’t do this at all on Windows 2000 yet the script is so remarkably simple for Windows XP and Windows Server 2003. (Did we mention that life isn’t fair? Well, it’s not.) Our script for modifying the KeepPrintedJobs property is a run-of-the-mill WMI script, one that starts out by connecting to the WMI service on the local computer. (Although, as usual, this works just as well on remote computers.) We then issue this query to return a collection of all the printers on the computer that have a DeviceID of ArtDepartmentPrinter:

Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where DeviceID = 'ArtDepartmentPrinter'")

Keep in mind that we did this because you specifically asked about changing the property value on a printer. In some cases, however, you might want to modify this property value for all the printers on a print server. If that’s the case, then simply remove the Where clause from the query. This query returns a collection of all the printers on a computer, enabling you to change the KeepPrintedJobs property for, say, each for the 150 or so printers on a print server:

Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")

And yes, that is why we like WMI so much.

As soon as we have our collection we set up a For Each loop to walk us through all the printers in the collection (again, for this particular script we’ll have only one printer, the printer with the DeviceID ArtDepartmentPrinter). Inside our For Each loop we find these two lines of code:

objPrinter.KeepPrintedJobs = False
objPrinter.Put_

Here we’re doing nothing more than setting the value of the KeepPrintedJobs property to False, then calling the Put_ method to actually save those changes to the printer. From this point on, ArtDepartmentPrinter will no longer save a copy of printed documents. That’s all there is to it.

As we noted earlier, you can’t modify this property on a Windows 2000 computer; you can, however, determine whether or not this property has been enabled on a Windows 2000 computer. This isn’t much of a consolation prize, but here’s a script that will do just that:

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where DeviceID = 'ArtDepartmentPrinter'")
     

For Each objPrinter in colPrinters
    If objPrinter.Attributes And 256 Then 
        Wscript.Echo "Printed documents are kept."
    Else
        Wscript.Echo "Printed documents are not kept."
    End If
Next

On a Windows 2000 computer, the KeepPrintedJobs property is part of a read-only “bitmask” property called Attributes. We won’t discuss bitmasks or the Attributes property in any detail today; instead we’ll simply point out that the KeepPrintedJobs property has an attribute value of 256. Because of that, we can use Boolean logic to determine whether KeepPrintedJobs is enabled or not. If this line of code is true, that means KeepPrintedJobs has been enabled:

If objPrinter.Attributes And 256 Then

Sure, it looks weird, but think of it in these terms: imagine there’s a switch on the computer that has a value of 256. If that switch is on then KeepPrintedJobs is enabled; if that switch is off then KeepPrintedJobs is disabled. All we’re doing is checking to see whether or not that switch is on or off.

Incidentally, and before you ask, we’re afraid the answer is no: it’s highly unlikely the version of WMI found on Windows 2000 will ever be updated to allow you to modify the KeepPrintedJobs property. Sorry.

Now, let’s see, is there any more bad news we can tell you about today? Well, now that you mention it….