回显一个进程是否在一系列远程计算机上运行

时间:2013-10-09 00:46:08

标签: vbscript

我正在尝试创建一个脚本,该脚本将连接到IP地址范围内的远程计算机,然后回显其中哪些正在运行explorer.exe进程。

当我在一个小范围内运行脚本(10.2.1.1 - 10.2.1.10)时,我知道10.2.1.4处于脱机状态,10.2.1.9和10.2.1.10不是基于Windows的计算机,因此应该回显“Explorer” .exe没有运行“但似乎并非如此。它们似乎返回与先前服务器相同的结果。例如,10.2.1.3有3个Explorer.exe实例和echo 3次,然后我得到10.2.1.4离线的相同结果。

我的脚本如下:

On Error Resume Next

intStartingAddress = InputBox("Please enter a starting address: (e.g. 1)", "Starting Address")
intEndingAddress = InputBox("Please enter an ending address: (e.g. 254)", "Ending Address")
strSubnet = InputBox("Please enter a subnet excluding the last octet: (e.g. 10.2.1.)", "Subnet")

For i = intStartingAddress to intEndingAddress
    strComputer = strSubnet & i

    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    Set colProcess = objWMIService.ExecQuery("Select * From Win32_Process Where Name = 'Explorer.exe'")

    For Each objProcess in colProcess
        If colProcess.Count > 0 Then
            Wscript.Echo strComputer & " Explorer.exe is running."
        Else
            Wscript.Echo strComputer & " Explorer.exe is not running."
        End If
    Next
Next

Wscript.Echo "That's all folks!"

2 个答案:

答案 0 :(得分:1)

首先:我会将colProcess.Count检查移到colProcess循环之前。如果对象中没有集合,则不会得到回应响应。

第二:我会在WMI查询中测试一个值,例如ProcessID,并检查它是否为Null,或者它是否有值,这意味着它实际上正在运行。

intStartingAddress = InputBox("Please enter a starting address: (e.g. 1)", "Starting Address")
intEndingAddress = InputBox("Please enter an ending address: (e.g. 254)", "Ending Address")
strSubnet = InputBox("Please enter a subnet excluding the last octet: (e.g. 10.2.1.)", "Subnet")

For i = intStartingAddress to intEndingAddress
    strComputer = strSubnet & i

    Set objWMIService = Nothing

    On Error Resume Next
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    On Error Goto 0

    If objWMIService Is Nothing Then
        Wscript.Echo strComputer & " Explorer.exe is not running."
    Else
        Set colProcess = objWMIService.ExecQuery("Select * From Win32_Process Where Name = 'Explorer.exe'")

        If colProcess.Count = 0 Then
            Wscript.Echo strComputer & " Explorer.exe is not running."
        Else
            For Each objProcess in colProcess
                If IsNull(objItem.ProcessID) Or Not IsNumeric(objItem.ProcessID) Then
                    Wscript.Echo strComputer & " Explorer.exe is not running."
                Else
                    Wscript.Echo strComputer & " Explorer.exe is running. (Process ID: " & objItem.ProcessID & ")"
                End If
            Next
        End If
    End If
Next

Wscript.Echo "That's all folks!"

编辑: 如Ansgar Wiechers所指出的,考虑到WMI查询的修改脚本将在非Windows操作系统上失败。

答案 1 :(得分:1)

是什么让您相信非Windows计算机会首先响应WMI查询?对于大多数非Windows计算机的声明

Set objWMIService = GetObject("winmgmts:" _
  & "{impersonationLevel=impersonate}!\\" _
  & strComputer & "\root\cimv2")

只会失败,因为它们不支持WMI(Windows Management Instrumentation的缩写)。由于此错误,objWMIService对象保持与上一个循环周期中的对象相同,因此您的后续指令将查询您之前执行的相同主机。但是,您永远不会看到错误,因为它被全局On Error Resume Next掩盖了。

可以通过删除全局On Error Resume Next并更改此循环来缓解此问题:

For i = intStartingAddress to intEndingAddress
  strComputer = strSubnet & i

  Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

  ...
Next

这样的事情:

For i = intStartingAddress to intEndingAddress
  strComputer = strSubnet & i
  Set objWMIService = Nothing

  On Error Resume Next
  Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" _
    & strComputer & "\root\cimv2")
  On Error Goto 0

  If Not objWMIService Is Nothing Then
    ...
  Else
    WScript.Echo strComputer & " cannot be accessed."
  End If
Next

通过将上述内容与ping测试结合起来,您可以区分无法访问的计算机和似乎没有运行Windows的计算机:

Set wmi = GetObject("winmgmts://./root/cimv2")

qry = "SELECT * FROM Win32_PingStatus WHERE Address='" & strComputer & "'"
For Each ping In wmi.ExecQuery(qry)
  reachable = (0 = ping.StatusCode)
Next

If reachable Then
  If objWMIService Is Nothing Then
    'computer is not running Windows
  Else
    'computer is running Windows
  End If
Else
  'computer is offline
End If