I need to know how to get average reply time from using ping command in the vbs.
I found out that I can get all ping output just executing this command but may be I can just get my time data and calculate in variable without using string handling.
Set objExec = objShell.Exec("ping -n 2 -w 1000 " & strTarget)
strPingResults = LCase(objExec.StdOut.ReadAll)
I would not recommend shelling out to ping.exe and then parsing the output. Use WMI instead:
target = 'somecomputer'
n = 2
Set wmi = GetObject("winmgmts://./root/cimv2")
qry = "SELECT * FROM Win32_PingStatus WHERE address='" & target & "'"
rspTime = 0
cnt = 0
For i = 1 To n
For Each pingStatus In wmi.ExecQuery(qry)
If Not IsNull(pingStatus.StatusCode) Or pingStatus.StatusCode = 0 Then
rspTime = rspTime + pingStatus.ResponseTime
cnt = cnt + 1
End If
Next
Next
If cnt > 0 Then
WScript.Echo "Average response time: " & (rspTime / cnt)
Else
WScript.Echo "Host unreachable"
End If
Related
I am looking for a way to ping a hostname via a VBScript and if it fails after some bad counts, if offline, it runs another vbs file.
I have many scripts that can ping a host via VBScript, but I don't know and I couldn't find a way to ping a host and if not pinging, to redirect and run another VBScript.
I've tried to add in the end of one of those scripts something like:
If strFailedPings = "" Then
WScript.Echo "Ping status of specified computers is OK"
Else
(here is the place that goes the code to open another vbs)
Example:
strComputers = "192.168.1.1,192.168.1.4"
arrComputers = Split(strComputers, ",")
For Each strComputer In arrComputers
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery("SELECT * from Win32_PingStatus WHERE address = '" & _
strComputer & "'")
For Each objPingStatus In objPing
If IsNull(objPingStatus.StatusCode) Or objPingStatus.StatusCode<>0 Then
If strFailedPings <> "" Then strFailedPings = strFailedPings & vbCrLf
strFailedPings = strFailedPings & strComputer
End If
Next
Next
If strFailedPings = "" Then
WScript.Echo "Ping status of specified computers is OK"
Else
WScript.Echo "Ping failed for the following computers:" & _
vbCrLf & vbCrLf & strFailedPings
End If
Run the WMI query n times in a For loop and count and count the failed pings, then run the other script if the fail count exceeds a given threshold.
n = 3
threshold = 1
Set wmi = GetObject("winmgmts://./root/cimv2")
For Each strComputer In arrComputers
qry = "SELECT * FROM Win32_PingStatus WHERE address='" & strComputer & "'"
cnt = 0
For i = 1 To n
For Each objPingStatus In wmi.ExecQuery(qry)
If IsNull(objPingStatus.StatusCode) Or objPingStatus.StatusCode<>0 Then
cnt = cnt + 1
End If
Next
Next
If cnt > threshold Then
'ping failed 2 or more times
CreateObject("WScript.Shell").Run "wscript.exe ""C:\other\script.vbs""", 0, True
End If
Next
Side note: you may want to distinguish between sNull(objPingStatus.StatusCode) and objPingStatus.StatusCode<>0. Only the latter represents the actual ping status. The former indicates a WMI error.
I don't think you can break up the GetObject line:
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT * from Win32_PingStatus WHERE address = '" & strComputer & "'")
When I run the script (I replaced the Echo with MsgBox but it shouldn't matter) it works fine:
strComputers = "192.168.1.1,192.168.1.4,100.100.100.100"
arrComputers = Split(strComputers, ",")
For Each strComputer In arrComputers
Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT * from Win32_PingStatus WHERE address = '" & strComputer & "'")
For Each objPingStatus In objPing
If IsNull(objPingStatus.StatusCode) Or objPingStatus.StatusCode <> 0 Then
If strFailedPings <> "" Then strFailedPings = strFailedPings & vbCrLf
strFailedPings = strFailedPings & strComputer
End If
Next
Next
If strFailedPings = "" Then
MsgBox "Ping status of specified computers is OK"
Else
MsgBox "Ping failed for the following computers:" & _
vbCrLf & vbCrLf & strFailedPings
End If
I don't know anyone that can read VBScript. I am wondering if anyone help me read the following statements?
Public Sub GetNodeName(CompIP)
Dim i
Dim ProcedureName
ProcedureName = "GetNodeName(CompIP): " & CompIP
ProcedureName = "ProcedureName & ": " & $Date & ": " & $Time
For i = To $CompName -> Size
If CompIP = $COMPUTER_IP[i] Then
$NodeNumber = i
$ComputerID = $CompName[i]
i = $CompName -> Size + 1
$DemoMode = 0
Else 'Demomode
$NodeNumber = 1
$DemoMode = 1
$ComputerID = "Demo Mode"
End If
Next
and
For i = 1 To $CompName -> Size
If $CompName[i] = NodeName Then
GetNodeNumber=i
'Exit Loop
i = $CompName -> Size + 1
End if
Next
If GetNodeName = -1 Then $Trace("Node not found")
ComputerName is TABLET4. IP Address is 172.10.10.7.
Whatever language that is, the intent of the code is clear.
The sub iterates through parallel arrays $CompName and $COMPUTER_IP two find the name of the computer ($CompName[i]) that corresponds to the provided id (CompIP).
If a match is found, it sets $NodeNumber to the index of the match, $ComputerID to the name of the computer, and $DemoMode to 0.
If no match is found, it sets $NodeNumber to 1, $ComputerID to Demo Mode, and $DemoMode to 1.
When you type the minute to be the same as the current minute (Ex. you type in 20 and its currently 1:20) I want it to end the script. Instead it gives me
Invalid procedure call or argument error.
Dim Ho, Mi, Se, RH, RM, RS
bOuterLoop = True
Do While bOuterLoop
reminder = InputBox(vbNewLine & "Enter a reminder for today," & " " &
WeekdayName(Weekday(Now())) & " " & MonthName (Month(Now)) & " " & (Day(Now)) & ", " & (Year(Now)) & "!", "Set a Reminder")
If IsEmpty(reminder) Then
WScript.Quit
End If
If reminder="" then
reminder="REMINDER FOR YOU"
end if
Ho = InputBox(vbNewLine & "At what hour would you like to be reminded?(24H)", "Time")
If IsEmpty(Ho) Then
WScript.Quit
End If
if Ho = "" then
WScript.Quit
End If
Mi = InputBox(vbNewLine & "At what minute in the hour do you want to be
reminded?", "Time")
If IsEmpty(Mi) Then
WScript.Quit
End If
if Mi = "" then
WScript.Quit
End If
RH = Hour(Now)
RM = Minute(Now)
RS = Second(Now)
if Mi = RM then
a=msgbox(reminder, 0, "")
wscript.quit
end if
Ho = Ho - RH
Se = RS
if RM > Mi then
Mi = Mi + 60
end if
Mi = Mi - RM
Do
WScript.Sleep (3600000 * Ho) + ((60000 * Mi) - (1000 * Se))
answer = MsgBox(reminder & " " & vbNewLine & vbNewLine & "Would you like to snooze the reminder? ", 4+64, "Reminder")
If answer = vbNo Then
WScript.Quit
bOuterLoop = False
Exit Do
End If
Loop
Loop
Please explain what I'm doing wrong.
I am not sure about the logic which you are using here but I think the 'If' condition comparing the values of variables 'Mi' and 'RM' is returning False.
Suppose the current time is 1:20.
In your code, the variable Mi stores the input taken from the user which is of type vbString. Suppose the user enters 20. So, your variable looks something like this:
Mi="20"
The variable RM stores Minute(now) which is of type vbInteger. So, it would look something like this:
RM=20
Now when you compare these two variables, they are not equal. Hence, the If condition returns False and your script does not end.
You can make the following change in your code:
If Cint(Mi) = RM then
a=msgbox(reminder, 0, "")
wscript.quit
End If
You guys did great helping me with one VBScript, so I'm going to throw another your way. Perhaps you can help me iron out the wrinkles.
My intention with this script is to rename the PC. The computer name is a combination of prompted text (something I provide, say a location code), a hyphen, and the last 10 digits of the computer's serial number called from WMIC. i.e. 1275-XXXXXXXXXX
My problems here are the following:
If my code is over 10 characters, it just errors out. I want to fix
that. I'm sure it's just the way I have it coded and nothing to do
with pulling from WMIC.
If it does error out pulling the serial number from WMIC, say because there's no value, I want to be prompted to enter something in it's place. Then at the end it will take Input1 (the location code) and Input2 (what I provide if the SN pull fails), smack a hyphen in the middle, and apply it.
My error out isn't working if it does fail. I don't know why.
I've found so many different solutions for renaming PC's either what I type in or specifically for pulling the SN, but not for my specific situation. Any help would be GREATLY appreciated, as always. :)
Here's my code:
'Rename computer by serial # v1.0 November 2009
dim Bios, BiosSerial, objFSO, objTextFile
'Const ForReading = 1, ForWriting = 2, ForAppending = 8
'get PropertyID
strInput = UserInput( "Enter the BHMS Property ID:" )
Function UserInput( myPrompt )
' This function prompts the user for some input.
' When the script runs in CSCRIPT.EXE, StdIn is used,
' otherwise the VBScript InputBox( ) function is used.
' myPrompt is the the text used to prompt the user for input.
' The function returns the input typed either on StdIn or in InputBox( ).
' Written by Rob van der Woude
' http://www.robvanderwoude.com
' Check if the script runs in CSCRIPT.EXE
If UCase( Right( WScript.FullName, 12 ) ) = "\CSCRIPT.EXE" Then
' If so, use StdIn and StdOut
WScript.StdOut.Write myPrompt & " "
UserInput = WScript.StdIn.ReadLine
Else
' If not, use InputBox( )
UserInput = InputBox( myPrompt )
End If
End Function
'Obtain Serial Number.
for each Bios in GetObject("winmgmts:").InstancesOf ("win32_bios")
BiosSerial = Bios.SerialNumber
exit for
next
strNewSN = BiosSerial
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) < 9 Then
strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput+"-"+strNewSN
End If
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
err = objComputer.Rename(strNewPCName)
if err <> 0 then
wscript.echo "There was an error renaming the PC. Please restart and try again, or rename it manually."
else
wscript.echo "PC successfully renamed: " & strNewPCName
end if
Next
5/29/2013 EDIT: I've made some changes based on your suggestion, and I'm getting on error on line 36 char 1 "Expected Statement" Code 800A0400. It looks fine to me so what am I missing? Here's a new paste of my code with line 36 notated.
dim Bios, BiosSerial, objFSO, objTextFile
'Const ForReading = 1, ForWriting = 2, ForAppending = 8
' Prompt for PropertyID
strInput = UserInput( "Enter the BHMS Property ID:" )
Function UserInput( myPrompt )
' Check if the script runs in CSCRIPT.EXE
If UCase( Right( WScript.FullName, 12 ) ) = "\CSCRIPT.EXE" Then
' If so, use StdIn and StdOut
WScript.StdOut.Write myPrompt & " "
UserInput = WScript.StdIn.ReadLine
Else
' If not, use InputBox( )
UserInput = InputBox( myPrompt )
End If
End Function
' Obtain Serial Number.
for each Bios in GetObject("winmgmts:").InstancesOf ("win32_bios")
BiosSerial = Bios.SerialNumber
exit for
next
strNewSN = BiosSerial
If IsEmpty(BiosSerial) Then
strNewSN = UserInput("There is no serial number listed in the BIOS. Provide an alternative: ")
Else
strNewSN = BiosSerial
End If
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
End If 'LINE36'
Set WshNetwork = WScript.CreateObject("WScript.Network")
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colComputers = objWMIService.ExecQuery _
("Select * from Win32_ComputerSystem")
For Each objComputer in colComputers
err = objComputer.Rename(strNewPCName)
On Error <> 0 Then
wscript.echo "There was an error renaming the PC. Please restart and try again, or rename it manually."
Else
wscript.echo "PC successfully renamed: " & strNewPCName
end if
Next
If my code is over 10 characters, it just errors out. I want to fix that. I'm sure it's just the way I have it coded and nothing to do with pulling from WMIC.
' If the SN is longer than 10 characters, truncate to the last 10.
If Len(strNewSN) < 9 Then
strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput+"-"+strNewSN
End If
Your comment says that you want to use the last 10 characters from the serial number if the serial number is longer than that, but your code takes the last 10 characters only if the serial number is shorter than 9 characters. Change that into
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
If it does error out pulling the serial number from WMIC, say because there's no value, I want to be prompted to enter something in it's place. Then at the end it will take Input1 (the location code) and Input2 (what I provide if the SN pull fails), smack a hyphen in the middle, and apply it.
You could use IsEmpty() to check if the BiosSerial variable has a value:
If IsEmpty(BiosSerial) Then
strNewSN = UserInput("Enter fake serial number:")
Else
strNewSN = BiosSerial
End If
My error out isn't working if it does fail. I don't know why.
Define "isn't working". What result do you get, and how is it different from the result you expect?
BTW, you shouldn't use err as a name for a variable. Err is an intrinsic object that VBScript provides in the context of handling terminating errors.
Edit: You have a spurious End If in line 36:
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
End If
Remove that line and the error will disappear.
In VBSCript an If statement can have two forms:
With closing End If:
If condition Then
instruction
End If
When using this form, instruction must not be on the same line as the Then keyword.
Without closing End If:
If condition Then instruction
When using this form, instruction must be on the same line as the Then keyword and must not be followed by an End If.
In line 34 of your code you truncate the serial number to 10 characters if it's longer than that, and then execute the next line regardless of whether the serial number had to be truncated or not (that line must be executed unconditionally, so I removed it from the Then branch):
If Len(strNewSN) > 10 Then strNewSN = Right(BiosSerial, 10)
strNewPCName = strInput & "-" & strNewSN
which is equivalent to this:
If Len(strNewSN) > 10 Then
strNewSN = Right(BiosSerial, 10)
End If
strNewPCName = strInput & "-" & strNewSN
I want to use a VB script (full script in the Pastebin) to check that certain servers are up (responding to pings) every time I log in to my work computer.
However, it seems that as I am grabbing the full results of the output...
strPingResultsFull = LCase(WshExec.StdOut.ReadAll)
...before I loop through the individual lines...
Do Until WshExec.StdOut.AtEndOfStream
...that WshExec.StdOut is already AtEndOfStream, so I'm never getting any results.
The first part of my questing - is this theory correct (or likely to be correct)? The second part - How do I sort this out (i.e. reset the stream so that I can check every line individually)? Thanks.
' Set the targets to ping
strTarget(0) = "192.168.1.6" ' TTSA
strTarget(1) = "192.168.1.7" ' TTSB
strTarget(2) = "192.168.1.14" ' TTSC
strTarget(3) = "192.168.1.12" ' TTSD
Set WshShell = WScript.CreateObject("WScript.Shell")
' Loop through all of the targets to ping
For i = 0 To UBound(strTarget)
' Ping the target
Set WshExec = WshShell.Exec("ping -n 2 -w 500 " & strTarget(i)) ' Send 2 echo requests, waiting 0.5 seconds maximum
' Grab the full results of the ping
strPingResultsFull = LCase(WshExec.StdOut.ReadAll)
' Set 'strPingResultsPart' to an empty string
strPingResultsPart = ""
' Grab the results of the ping
Do Until WshExec.StdOut.AtEndOfStream
strSingleLine = WshExec.StdOut.ReadLine()
If Instr(strSingleLine, "Ping statistics for") <> 0 Or Instr(strSingleLine, "Packets:") <> 0 Then
strPingResultsPart = strPingResultsPart & strSingleLine
End If
Loop
' Check that there is something to output (there should be, even if the pings all fail)
If strPingResultsPart <> "" Then
Msgbox "Not empty - " & strPingResultsPart
' Add the ping results to the correct results strings
If InStr(strPingResultsFull, "reply from") Then
strOutputSuccess = strOutputSuccess & strPingResultsPart & VBCrLf
Else
strOutputFailure = strOutputFailure & strPingResultsPart & VBCrLf
End If
End If
Set WshExec = Nothing
Next
After first call WshExec.StdOut.ReadAll you're already at AtEndOfStream therefore...
Do Until WshExec.StdOut.AtEndOfStream
...will do nothing. You can't seek back StdOut to read from it multiple times.