Пропуск компьютеров с ошибкой

У меня проблема с VBScript, который ищет принтеры на компьютерах из списка на листе Excel и затем находит их через WMI. Он сопоставляет их по имени IP-адреса, а затем записывает командный файл, из которого я могу установить их. Моя проблема в том, что когда у меня выключен компьютер, я получаю ошибку 462, которая затем очищается, но затем принтеры для предыдущего компьютера записываются снова. Я довольно новичок в этом, поэтому я не уверен, что мне здесь чего-то не хватает.

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

1 ответ

Что происходит, это:

  1. On Error Resume Next

    Это включает обработку ошибок (или, скорее, подавление ошибок) для остальной части сценария, поскольку он никогда не отключается.

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

    Эта команда не выполняется, потому что strComputer не достижимо Из-за ошибки переменная Err установлен и objWMIService сохраняет прежнее значение

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

    Эта команда завершается успешно и перечитывает список принтеров с предыдущего компьютера, поскольку objWMIService по-прежнему относится к этому компьютеру.

  4. For Each objPrinter in colPrinters

    Сценарий входит в цикл, потому что colPrinters заполнились принтерами с предыдущего компьютера (снова),…

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

    … но потому что Err все еще установлен, скрипт переходит в Else ветка, где ошибка сообщается и очищается:

    objFile.WriteLine "REM " & strComputer & " - Error:  " & err.number
    Err.Clear
    
  6. Затем скрипт переходит к следующей итерации цикла. Err теперь очищен, поэтому остальные принтеры в colPrinters обрабатывается нормально.

Глобальный On Error Resume Next это корень всего зла. Не делай этого. КОГДА-ЛИБО.

Если вам абсолютно необходимо использовать On Error Resume Next включите локальную обработку ошибок, поместите некоторый фактический код обработки ошибок на место и сразу же отключите обработку ошибок. В вашем случае это можно реализовать так:

...
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 = ""
...
Другие вопросы по тегам