【问题标题】:How to handle unavailable computers in WMI connections?如何处理 WMI 连接中不可用的计算机?
【发布时间】:2014-07-17 05:07:10
【问题描述】:

我想评估连接到我的域的计算机的内存和其他详细信息。我正在做的是将计算机名称写入文本文件中,每行一个。脚本将一一读取文件(主机名),收集信息并将其写入文件。这工作正常。

问题是,如果一台计算机不可用,那么它就会出现问题。例如,如果第一个主机名可用而第二个不可用,则它会不断重复显示相同的信息。

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

【问题讨论】:

标签: vbscript wmi


【解决方案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 并完全删除注册表查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2013-07-08
    • 2011-03-09
    • 1970-01-01
    • 2011-06-28
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多