我有一个包含数百台计算机的环境。我正在尝试编写运行并添加适当打印机的 vBscript。可以使用有关计算机名称的线索来确定打印机名称。我的脚本(由于调试而有点脏)如下:
'Key vars
printServer = "SERVER"
Set WshNetwork = CreateObject("WScript.Network")
'Extract computer name and take the first two fields
cNameParts=Split(WshNetwork.ComputerName,"-")
printerNamePrefix = cNameParts(0) + "-P" + cNameParts(1)
Set objWMIService = GetObject("winmgmts:\\" & printServer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select Name from Win32_Printer WHERE Name LIKE '" + printerNamePrefix + "-%'",,48)
'Set colItems = objWMIService.ExecQuery("Select Name from Win32_Printer",,48)
Wscript.Echo "Done querying.."
printerName = ""
For Each printerObj in colItems
printerName = printerObj.Name
Wscript.Echo printerName
Next
PrinterPath = "\\" + UCASE(printServer) + "\" + printerName
Wscript.Echo "Adding " + PrinterPath
WshNetwork.AddWindowsPrinterConnection PrinterPath, PrinterDriver
WshNetwork.SetDefaultPrinter PrinterPath
现在 WMI 似乎非常慢,并且占用了服务器上的 CPU。当我注释第一个查询并取消注释第二个查询(以枚举所有打印机)时,它似乎通过输出进行缓冲:
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
(wait a few sec)
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
PRINTER_NAME
(wait a few sec)
我知道 WMI 返回异步,这就是为什么“done querying”首先打印的原因。现在显然“net view”不使用 WMI,因为它速度超快。我可以编写一个 VBScript 来解析“net view”,但这似乎很笨拙。有更好的方法吗?
答案1
“Win32_Printer”和“net view”查询不同的对象。“Win32_Printer”将枚举所有已安装的打印机对象,在打印服务器上可能会非常慢。这将公开大量好的数据和一些管理功能。但是,您只对队列的名称感兴趣,因此这可能超出了您的需求。另一方面,“net view”查询共享对象的列表。它不会返回太多数据,也不会公开任何管理功能,但运行速度要快得多。您可以使用“Win32_Share”对象通过 WMI 模拟此操作。
对于您的代码,尝试将您的 WMI 查询从
Set colItems = objWMIService.ExecQuery("Select Name from Win32_Printer WHERE Name LIKE '" + printerNamePrefix + "-%'",,48)
到
Set colItems = objWMIService.ExecQuery("Select Name from Win32_Share WHERE Name LIKE '" + printerNamePrefix + "-%'",,48)
请注意,我刚刚将“Win32_Printer”更改为“Win32_Share”。这将查询服务器上的共享对象列表,并且运行速度会更快。但请注意,这将仅返回共享打印机的列表。对于打印服务器来说,这可能没问题,因为您感兴趣的打印机可能也是共享的。