Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Finding active hosts

Status
Not open for further replies.

acl03

MIS
Jun 13, 2005
1,077
US
I am trying to write a script that will test a range of IP addresses to find machines that are on.

I wrote and ran a script last night that pings every machine in a subnet, and writes out a file with the ones that responded. The problem is that it missed a bunch of machines I know were on overnight.

So I thought, maybe ping is not the best method. Maybe Ill use WMI to attempt to pull the computer name out of each IP in the loop. The ones that work are on, the ones that don't...are off. The problem here is that the unresponsive ones take nearly 20 seconds to timeout and move to the next one, making the script take way too long.

Questions:

1. Is there a better way to do this?
2. Is there a way to do have a VBS attempt a task for a certain amount of time then move on? I would like to lower the timeout on getting the computer name to 2 or 3 seconds, instead of nearly 20.

Here's my current working version of the script, it pings machines, and for every IP in the loop, it attempts to get the computer name as well.

Code:
Dim strHost
Dim strResultText
On Error Resume Next

fixedMonth = Right("0" & Month(Now),2)
fixedDay = Right("0" & Day(Now),2)
fixedHour = Right("0" & hour(Now), 2)
fixedMin = Right("0" & Minute(Now), 2)

outputFileName = ".\scripts\pingResults\" & Year(Date) & "-" & fixedMonth & "-" & fixedDay & " " & fixedHour & fixedMin & " Live PCs.csv"
Dim oShell
Set oShell = CreateObject("Wscript.Shell")

strResultText = "IP,Host,Date-Time" & vbCrLf

For octet3 = 153 To 155
	For octet4 = 1 To 255
		strHost = "192.168." & octet3 & "." & octet4
		ping strHost
	Next
Next

Const ForWriting = 2

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile (outputFileName, ForWriting, True)

Set objWMIService=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _ 
    strComputer & "\root\cimv2")
Set colServices = objWMIService.ExecQuery("Select * from Win32_Service")

For Each objService in colServices    
    objTextFile.WriteLine(strResultText)
Next
objTextFile.Close
	
'Wscript.echo "Done."



Function ping(strHost)


    dim objPing, objRetStatus
    set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery ("select * from Win32_PingStatus where address = '" & strHost & "'")

    For Each objRetStatus in objPing
        if IsNull(objRetStatus.StatusCode) or objRetStatus.StatusCode<>0 Then
    		pingSuccess = False
        Else
            pingSuccess = True
        end if
    Next
	MsgBox "1"
	hostName = getComputerName (strHost)
	
	MsgBox "2"
		
	If pingSuccess = True Then
	    strResultText = strResultText & strHost & "," & hostName & "," & Now & ",yes" & vbCrLf
	Else
    	strResultText = strResultText & strHost & "," & hostName & "," & Now & ",no" & vbCrLf
	End If
	MsgBox strResultText
	
End Function 


Function getComputerName(strHost)
	Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strHost & "\root\cimv2")
	Set colComputers = objWMIService.ExecQuery ("Select * from Win32_ComputerSystem")
	
	For Each objComputer in colComputers
		getComputerName = objComputer.Name
	Next 
	
End Function

Thanks,
Andrew

[smarty] Hard work often pays off over time, but procrastination pays off right now!
 
What if instead you simply just ping, pause a sec, ping again and if both returned false...then assume it is offline. I remember seeing post an example of using the async method of WMI to query multiple machines at the same time which may be another alternative...I'll post the link if I remember where I saw it.

--------------------------------------------------------------------------------
dm4ever
My philosophy: K.I.S.S - Keep It Simple Stupid
 
Adding a second ping would certainly make it more accurate...but it still wouldn't be as accurate as trying to pull all machine names, right? I guess it would be a lot faster, though.

Thanks,
Andrew

[smarty] Hard work often pays off over time, but procrastination pays off right now!
 
Appreciate the quick responses.

That script you linked certainly looks useful, but it might take me a week to figure out what it's doing :)



Thanks,
Andrew

[smarty] Hard work often pays off over time, but procrastination pays off right now!
 
Reduce the number of pings to 1 and its TTL to 100 millisecs.

Code:
function ping (strComputer)
   ping = false
   set objExec = objShell.Exec("%comspec% /c ping.exe " & strComputer & " -n 1 -w 100")

   do until objExec.Stdout.AtEndOfStream
      strLine = objExec.StdOut.ReadLine
      if (inStr(strLine, "Reply")) then ping = true
   loop
end function

if(ping(strComputer)) then 
   'Query WMI to get computer properties
end if


-Geates
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top