0

I'm having an issue with a VBScript that looks for printers on computers from a list on an Excel sheet and then finds them through WMI. It matches them through the IP address name and then writes a batch file that I can install them from. My issue is that when I have a computer that is turned off I get a 462 error which is then cleared but then the printers for the previous computer are written again. I'm quite new at this so I'm not sure if I'm just missing something really basic here.

Batch = "printerOutput.txt"
Const ForWriting = 2 'Set to 8 for appending data
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(Batch, ForWriting)

On Error Resume Next

Dim printerDictionary 'Create Printer dictionary of names and IP addresses
        Set printerDictionary = CreateObject("Scripting.Dictionary")
            printerDictionary.Add "Printer","xxx.xxx.xxx.xxx"


Set objExcel_1 = CreateObject("Excel.Application")
' Statement will open the Excel Workbook needed.

Set objWorkbook = objExcel_1.Workbooks.Open _
("x\p.xls")

If Err.Number <> 0 Then
    MsgBox "File not Found"
    Wscript.Quit

End If
'Checks for errors
f = 1 'Sets variable that will loop through Excel column


Do

' Msgbox f,, "Begining of Do Loop"


    strComputer = objExcel_1.Cells(f, 1).Value
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")      
    Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
    For Each objPrinter in colPrinters 'For ever objPrinter found in the computers WMIService


    If Err.Number = 0 Then

            objFile.WriteLine Err.Number
            If InStr(ObjPrinter.PortName,".") = 4 then 'If the printers IP port name is written like 128.xxx.xxx.xxx

                'MsgBox ObjPrinter.Name & " " & ObjPrinter.PortName,, "IfStatement"
                PrtDict ObjPrinter.PortName, StrComputer

            ElseIf InStr(ObjPrinter.PortName,"_") = 3 Then 'If the printers IP port name is written like IP_128.xxx.xxx.xxx
                cleanIP = GetIPAddress(objPrinter.PortName) 'Clean IP

                PrtDict cleanIP, StrComputer        
            End If

    Else

        objFile.WriteLine "REM " & strComputer & " - Error:  " & err.number
        Err.Clear

    End If

    Next



    f = f + 1


Loop Until objExcel_1.Cells(f, 1).Value = ""

objExcel_1.ActiveWorkbook.Close
ObjExcel_1.Quit

Function PrtDict(PrtMn, CMP) 'Loops through the dictionary to find a match from the IP address found


        For Each x in printerDictionary
            'MsgBox PrtMn & "=" & printerDictionary.Item(x),,"InPtrDict"
            If printerDictionary.Item(x) = PrtMn Then

                objFile.WriteLine "psexec -u \%1 -p %2 " & CMP & " path\" & x & ".bat"

            End If
        Next

End Function
'100
Function GetIPAddress(Address) 'For cleaning up IP address with names like IP_128.xxx.xxx.xxx

    IPtext = InStr(Address,"_")
    IPaddress = len(Address) - IPtext

GetIPAddress = Right(Address,IPaddress)
End Function
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574

1 Answers1

0

What happens is this:

  1. On Error Resume Next

    This enables error-handling (or rather error suppression) for the rest of the script, since it's never disabled.

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

    This command fails, because strComputer is not reachable. Because of the error the variable Err is set and objWMIService retains its previous value.

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

    This command succeeds and re-reads the printer list from the previous computer, because objWMIService still refers to that computer.

  4. For Each objPrinter in colPrinters

    The script enters the loop, because colPrinters got populated with the printers from the previous computer (again), …

  5. If Err.Number = 0 Then ... Else ... End If

    … but because Err is still set, the script goes into the Else branch, where the error is reported and cleared:

    objFile.WriteLine "REM " & strComputer & " - Error:  " & err.number
    Err.Clear
    
  6. Then the script goes into the next iteration of the loop. Err is now cleared, so the rest of the printers in colPrinters is being processed normally.

Global On Error Resume Next is the root of all evil. Don't do this. EVER.

If you absolutely must use On Error Resume Next, enable error-handling locally, put some actual error handling code in place, and disable error-handling right afterwards. In your case one might implement it like this:

...
Do
  strComputer = objExcel_1.Cells(f, 1).Value
  On Error Resume Next
  Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
  If Err Then
    objFile.WriteLine "REM " & strComputer & " - Error:  " & err.number
    Set objWMIService = Nothing
  End If
  On Error Goto 0

  If Not objWMIService Is Nothing Then
    Set colPrinters = objWMIService.ExecQuery("Select * From Win32_Printer")
    For Each objPrinter in colPrinters
      ...
    Next
    f = f + 1
  End If
Loop Until objExcel_1.Cells(f, 1).Value = ""
...
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328