Как обрабатывать недоступные компьютеры в соединениях WMI?

Я хочу оценить объем памяти и другие параметры компьютеров, подключенных к моему домену. Что я делаю, так это записываю имя компьютера в текстовый файл, по одному в строке. Скрипт будет читать файл (имя хоста) один за другим, собирать информацию и записывать ее в файл. Это работает нормально.

Проблема в том, что если один компьютер недоступен, то это создает проблемы. Например, если первое имя хоста доступно, а второе — нет, то будет постоянно отображаться одна и та же информация.

INPUT_FILE_NAME = "D:\tmp\Computer.txt"
Const FOR_READING = 1
Const HKEY_LOCAL_MACHINE = &H80000002
strRegKey = "SYSTEM\CurrentControlSet\Services\Tcpip\Parameters"

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile(INPUT_FILE_NAME, FOR_READING)
strComputers = objFile.ReadAll
objFile.Close

arrComputers = Split(strComputers, vbCrLf)

For Each strComputer In arrComputers
  On Error Resume Next
  Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
    "//./root/default:StdRegProv")
  objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname

  Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
  Set colPageFiles = objWMIService.ExecQuery _
    ("Select * from Win32_PageFileUsage")
  For each objPageFile in colPageFiles
    Wscript.Echo "Host Name: " & strHostName, _
      "AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
      "CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
      "Description: "& vbTab & objPageFile.Description, _
      "InstallDate: "& vbTab & objPageFile.InstallDate, _
      "Name: " & vbTab & objPageFile.Name, _
      "PeakUsage: " & vbTab &  objPageFile.PeakUsage
  Next
Next

person Sunil Kumar    schedule 17.07.2014    source источник
comment
Вы используете OERN без проверки успешности/неуспешности важных действий. См. stackoverflow.com/a/24685438/603855 и ссылку там для стратегии приличного обращения с "исключениями".   -  person Ekkehard.Horner    schedule 17.07.2014


Ответы (1)


Когда GetObject() терпит неудачу, переменная objWMIService сохраняет свое предыдущее значение, поэтому вы снова и снова сообщаете об одном и том же хосте, пока либо GetObject() не сможет подключиться к хосту, либо цикл не завершится. Измените это:

Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colPageFiles = objWMIService.ExecQuery _
  ("Select * from Win32_PageFileUsage")
For each objPageFile in colPageFiles
  Wscript.Echo "Host Name: " & strHostName, _
    "AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
    "CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
    "Description: "& vbTab & objPageFile.Description, _
    "InstallDate: "& vbTab & objPageFile.InstallDate, _
    "Name: " & vbTab & objPageFile.Name, _
    "PeakUsage: " & vbTab &  objPageFile.PeakUsage
Next

в это:

Set objWMIService = Nothing
Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
If Not objWMIService Is Nothing Then
  Set colPageFiles = objWMIService.ExecQuery _
    ("Select * from Win32_PageFileUsage")
  For each objPageFile in colPageFiles
    Wscript.Echo "Host Name: " & strHostName, _
      "AllocatedBaseSize: "& vbTab & objPageFile.AllocatedBaseSize, _
      "CurrentUsage: "& vbTab & objPageFile.CurrentUsage, _
      "Description: "& vbTab & objPageFile.Description, _
      "InstallDate: "& vbTab & objPageFile.InstallDate, _
      "Name: " & vbTab & objPageFile.Name, _
      "PeakUsage: " & vbTab &  objPageFile.PeakUsage
  Next
Else
  WScript.Echo strComputer & " unavailable."
End If

и проблема исчезнет.


С другой стороны, первые 2 строки во внешнем цикле всегда будут получать имя хоста вашего локального компьютера:

Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
  "//./root/default:StdRegProv")
objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname

Если это то, что вы действительно хотите, вы должны переместить код за пределы цикла, потому что значение strHostname не изменится:

Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!" & _
  "//./root/default:StdRegProv")
objReg.GetStringValue HKEY_LOCAL_MACHINE, strRegKey, "Hostname", strHostname
For Each strComputer In arrComputers
  '...
Next

Если вам действительно нужно имя удаленного компьютера (что имело бы гораздо больше смысла, когда остальная информация также поступает с удаленного компьютера), вы можете просто использовать strComputer и полностью удалить запрос реестра.

person Ansgar Wiechers    schedule 17.07.2014