0

I have an environment with several hundred computers. I am trying to write vBscript that runs and adds the appropriate printer. The printer names can be determined using clues about the computer name. My script (a little dirty due to debugging) is as follows:

'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 

Now WMI seems to be painfully slow and pegs the CPU on the server. When I comment the first query and uncomment the second (to enumerate all printers) it seems to buffer by outputting:

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)

I know WMI returns async, that's why "done querying" prints first. Now apparently "net view" doesn't use WMI since it is super fast. I could write a VBScript to parse "net view" but that seems very clunky. Is there a better way?

asdffffff
  • 109
  • 1
  • 5
  • Is PowerShelll an option? There's your "better way," but given server 2003, it seems like it might not be an option you have available. – HopelessN00b Feb 26 '14 at 14:40
  • I tried in PowerShell. The "PowerShell way" seems to be to use Get-WmiObject which is the exact same thing that VBScript is doing it. PowerShell runs just as slow. It's not a server 2003\2008 thing, these scripts are ran on the client machine. The PowerShell issue would be that some of the clients are XP. – asdffffff Feb 26 '14 at 16:40
  • Hmm. I don't see that behavior in PowerShell, even querying our under-provisioned 2003 print server. It's about as fast as `net view`, (sub-second delay between pages of output), and it doesn't seem to spike the CPU. Maybe your use case calls for something hideous-sounding, like VBScript to parse `net view` output, though. – HopelessN00b Feb 26 '14 at 17:06
  • Maybe you can query the registry key 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Printers' – ZEDA-NL Apr 18 '14 at 12:06

1 Answers1

1

"Win32_Printer" and "net view" are querying different objects. "Win32_Printer" will enumerate all installed printer objects and can be quite slow on print servers. This will expose lots of good data and some management functions. However, you're only interested in the names of queues, so this is probably over-kill for your needs. "net view" on the other hand queries for a list of shared objects. It doesn't return nearly as much data, or expose any management functions, but it does run a lot faster. You can mimic this with WMI by using the "Win32_Share" object.

For your code, try changing your WMI query from

Set colItems = objWMIService.ExecQuery("Select Name from Win32_Printer WHERE Name LIKE '" + printerNamePrefix + "-%'",,48)

to

Set colItems = objWMIService.ExecQuery("Select Name from Win32_Share WHERE Name LIKE '" + printerNamePrefix + "-%'",,48)

Note that I just changed 'Win32_Printer' to 'Win32_Share'. This will query the list of shared objects on the server and should run much faster. Be warned though, that this will only return a list of SHARED printers. This is probably OK for a print server, where the printers your are interested in are probably also shared.

MikeAtWake
  • 11
  • 1