问:

您好,脚本专家!如何禁用打印机上的“保留打印的文档”属性?

-- JJ

答:

您好,JJ。您未提到在哪种操作系统上尝试此操作,但我们希望是装有 Windows XP 或 Windows Servers 2003 的计算机。为什么?嗯,在装有 Windows XP 或 Windows Servers 2003 的计算机上,这非常容易做到;在其他版本的 Windows 上有点儿难。有多难?嗯,坦白地讲,完全不可能。

确实使得这一任务难以实现。

是的,我们知道:这公平。但生活就是如此。对于 Windows XP,WMI 类 Win32_Printer 已升级为包含一个新的读/写属性:KeepPrintedJobs。您可能已经猜到了,我们仅需切换该属性值即可保留(或不保留)指定打印机的打印机作业。遗憾的是,该属性不存在于任何 Windows XP 之前版本的 Windows 中。至于说 Windows 2000,我们可以使用脚本来告诉我们是否启用了打印机上的该属性,但实际上我们并不能改变该值。

注意:令人沮丧的是,ADSI(通常在 Windows 2000 中为打印机管理提供便捷的解决方法)在这里对我们并没有多大用处。确实存在一个新的 ADSI 属性,可供配置“保留打印的文档”属性使用,但它对您的 Windows 2000 计算机不会有任何帮助。

但是,假设您正在使用 Windows XP 或 Windows Server 2003,那么,可以使用如下脚本来禁用“保留打印的文档”属性:

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

我们知道:这似乎确实很不公平,您在 Windows 2000 上做不到这一点,而对于 Windows XP 和 Windows Server 2003 而言,这个脚本又非常简单。(我们不是曾提到生活是不公平的吗?嗯,事实并非如此。)用于修改 KeepPrintedJobs 属性的脚本只是一个普通的 WMI 脚本,其首先连接到本地计算机的 WMI 服务上。(尽管通常情况下这对远程计算机同样适用。)然后,我们发出以下查询,以返回计算机上所有 DeviceIDArtDepartmentPrinter 的打印机的集合:

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

请记住,我们这么做是因为您专门询问了更改单个打印机上属性值的方式。不过,在某些情况下,您可能要修改打印服务器上所有打印机的该属性值。如果是这种情况,只需从查询中删除 Where 子句即可。此查询将返回计算机上所有打印机的集合,使您可以每次更改打印服务器上大约 150 个打印机的 KeepPrintedJobs 属性:

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

是的,这就是我们如此喜欢 WMI 的原因所在。

得到集合后,我们建立一个 For Each 循环以遍历该集合内的所有打印机(另外,对于这个特定的脚本我们仅使用一个打印机,其 DeviceID 为 ArtDepartmentPrinter)。在 For Each 循环内部我们找到了以下两行代码:

objPrinter.KeepPrintedJobs = FalseobjPrinter.Put_

这里,我们只是将 KeepPrintedJobs 属性的值设置为 False,然后对 Put_ 方法的调用实际上是将所作更改保存到打印机上。此后,ArtDepartmentPrinter 将不再保存打印文档的副本。就这么简单。

正如我们前面说过的,您无法在 Windows 2000 计算机上修改此属性;不过,您可以决定是否在 Windows 2000 计算机上启用此属性。这不过是一种安慰奖,以下是实现此操作的脚本:

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 IfNext

在 Windows 2000 计算机上,KeepPrintedJobs 属性是只读属性“bitmask”的一部分,称为 Attributes。今天我们将不详细讨论 bitmasks 或 Attributes 属性;我们只是指明 KeepPrintedJobs 属性包含一个等于 256 的属性值。正因如此,我们可以使用布尔逻辑来决定是否启用 KeepPrintedJobs。如果此行代码为真,则表示已启用 KeepPrintedJobs:

If objPrinter.Attributes And 256 Then

的确,这看起来有些不可思议,但请思考一下以下内容:假设计算机上有一个开关,该开关的值为 256。如果开关打开,则启用 KeepPrintedJobs;如果开关关闭,则禁用 KeepPrintedJobs。我们所要做的只是查看开关是否已打开。

顺便说一下,在您提问之前,我们曾担心答案是否定的:Windows 2000 上的 WMI 版本根本不可能升级到允许修改 KeepPrintedJobs 属性的版本。很抱歉。