我正在尝试创建一个脚本,该脚本将连接到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!"
答案 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