Назад | Перейти на главную страницу

Альтернатива WMI для запросов к общим принтерам

У меня есть среда с несколькими сотнями компьютеров. Я пытаюсь написать 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 кажется очень медленным и привязывает процессор к серверу. Когда я комментирую первый запрос и раскомментирую второй (чтобы перечислить все принтеры), кажется, что он буферизируется, выводя:

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 возвращает асинхронный режим, поэтому сначала печатается "завершенный запрос". Теперь очевидно, что "net view" не использует WMI, поскольку он очень быстрый. Я мог бы написать VBScript для анализа «сетевого представления», но это кажется очень неуклюжим. Есть ли способ лучше?

Win32_Printer и net view запрашивают разные объекты. «Win32_Printer» перечислит все установленные объекты принтеров и может быть довольно медленным на серверах печати. Это откроет множество хороших данных и некоторые функции управления. Однако вас интересуют только имена очередей, так что это, вероятно, перебор для ваших нужд. "net view", с другой стороны, запрашивает список общих объектов. Он не возвращает столько данных и не предоставляет никаких функций управления, но работает намного быстрее. Вы можете имитировать это с помощью WMI, используя объект «Win32_Share».

Для вашего кода попробуйте изменить запрос 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». Это запросит список общих объектов на сервере и должен работать намного быстрее. Имейте в виду, что это вернет только список ОБЩИХ принтеров. Это, вероятно, нормально для сервера печати, где интересующие вас принтеры, вероятно, также используются совместно.