Excutes a ping action to a target computer with interval and samples

Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples.Probe (ProbeActionModuleType)

This probe module type runs a VBscript that pings the target computer with a specific interval and samples given parameters.

Knowledge Base article:

Summary

This probe module type runs a VBscript that pings the target computer with a specific interval and samples given parameters to obtain a property bag.

Element properties:

TypeProbeActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
Probe ProbeAction Microsoft.Windows.ScriptPropertyBagProbe Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
ComputerSourcePingstring$Config/ComputerSourcePing$Source Computer
NetworkTargetToPingstring$Config/NetworkTargetToPing$Target Computer
PingSamplesint$Config/PingSamples$Ping Samples
IntervalMillisecondsint$Config/IntervalMilliseconds$Interval Milliseconds
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds
LogEventsbool$Config/LogEvents$Log Events

Source Code:

<ProbeActionModuleType ID="Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples.Probe" Accessibility="Internal" Batching="false" PassThrough="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ComputerSourcePing" type="xsd:string">
<xsd:annotation>
<xsd:documentation>This should always be the Windows Computer PrincipalName since this is going to be where we connect to WMI and ping from</xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="NetworkTargetToPing" type="xsd:string"/>
<xsd:element name="PingSamples" type="xsd:unsignedInt"/>
<xsd:element name="IntervalMilliseconds" type="xsd:integer"/>
<xsd:element name="TimeoutSeconds" type="xsd:integer"/>
<xsd:element name="LogEvents" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="ComputerSourcePing" Selector="$Config/ComputerSourcePing$" ParameterType="string"/>
<OverrideableParameter ID="NetworkTargetToPing" Selector="$Config/NetworkTargetToPing$" ParameterType="string"/>
<OverrideableParameter ID="PingSamples" Selector="$Config/PingSamples$" ParameterType="int"/>
<OverrideableParameter ID="IntervalMilliseconds" Selector="$Config/IntervalMilliseconds$" ParameterType="int"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
<OverrideableParameter ID="LogEvents" Selector="$Config/LogEvents$" ParameterType="bool"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<ProbeAction ID="Probe" TypeID="Windows!Microsoft.Windows.ScriptPropertyBagProbe">
<ScriptName>Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples.vbs</ScriptName>
<Arguments>"$Config/ComputerSourcePing$" "$Config/NetworkTargetToPing$" "$Config/PingSamples$" "$Config/IntervalMilliseconds$" "$Config/LogEvents$"</Arguments>
<ScriptBody><Script>
'Copyright (c) Microsoft Corporation. All rights reserved.

'*************************************************************************
' $ScriptName: "Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples" $
'
' Purpose: This script runs a WMI query to ping a target computer to check if it is available in the network.
'
' $File: Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples.vbs $
'*************************************************************************

Option Explicit
SetLocale("en-us")

'Define local event constants
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

'Other constants
Const SCRIPT_NAME = "Microsoft.SystemCenter.ICMPProbe.WithConsecutiveSamples"
' Event ID Constants
Const EVENTID_LOGINFORMATION = 100
Const EVENTID_SUCCESS = 99
Const EVENTID_SCRIPT_ERROR = 1000

Const APP_DISCOVERY_CONNECT_FAILURE = -1
Const APP_DISCOVERY_QUERY_FAILURE = -2
Const REGISTRY_CONNECT_FAILURE = -3
Const REGISTRY_READ_FAILURE = -4
Const HKEY_CLASSES_ROOT = &amp;H80000000
Const HKEY_CURRENT_USER = &amp;H80000001
Const HKEY_LOCAL_MACHINE = &amp;H80000002
Const HKEY_USERS = &amp;H80000003
Const HKEY_CURRENT_CONFIG = &amp;H80000005
Const StateDataType = 3


Dim oAPI, oBagState
Dim oParams, bLogSuccessEvent
Dim strErrorDetail, strMessage
Dim dtStart

Dim SourceComputerToPing, TargetComputerToPing, intPingSamples, intervalMilliseconds, strPingStatus, intStatus
Dim objWMIService, oPropertyBag, colItems, objItem
Dim strStatusCode, strResponseTime, boolPing

dtStart = Now
strStatusCode = "11003"
strResponseTime = "0"

Set oAPI = MomCreateObject("Mom.ScriptAPI")

Set oParams = WScript.Arguments
if oParams.Count &lt; 5 then
strMessage = "The script '" &amp; SCRIPT_NAME &amp; "' didn't execute successfully because some parameters were missing: Param Count(" &amp; CStr(oParams.Count) &amp; ")"
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_INFORMATION, strMessage
Wscript.Quit -1
End if

SourceComputerToPing = oParams(0)
TargetComputerToPing = oParams(1)
intPingSamples = CInt(oParams(2))
intervalMilliseconds = CInt(oParams(3))
bLogSuccessEvent = CBool(oParams(4))

Set oPropertyBag = oAPI.CreatePropertyBag()

If Trim(SourceComputerToPing) = "" Then
SourceComputerToPing = "."
End If

If bLogSuccessEvent = true Then
strMessage = "Script executed with these parameters: SourceComputerToPing: " &amp; SourceComputerToPing &amp; " TargetComputerToPing: " &amp; TargetComputerToPing &amp; " PingSamples: " &amp; oParams(2) &amp; " intervalMilliseconds: " &amp; oParams(3)
call CreateEvent(EVENTID_LOGINFORMATION, EVENT_TYPE_INFORMATION, strMessage)
End If

Dim ObjError
Dim itmPing
Set ObjError = New Error

On Error Resume Next

For itmPing = 1 To intPingSamples
If bLogSuccessEvent = true Then
strMessage = "Executing Ping Number " &amp; CStr(itmPing)
call CreateEvent(EVENTID_LOGINFORMATION, EVENT_TYPE_INFORMATION, strMessage)
End If

boolPing = PingComputer(SourceComputerToPing, TargetComputerToPing)

If bLogSuccessEvent = true Then
strMessage = "Ping Number " &amp; CStr(itmPing) &amp; " Result: " &amp; CStr(boolPing)
call CreateEvent(EVENTID_LOGINFORMATION, EVENT_TYPE_INFORMATION, strMessage)
End If


If boolPing = True Then
Exit For
End If

If itmPing &lt; intPingSamples Then
Wscript.Sleep(intervalMilliseconds)
End If
Next

'this is to check whether the previous ping from primary management server to agent was successfully received from agent. if not then we try to find the parent of agent and try the ping from there one more time.
If strStatusCode &lt;&gt; "0" Then
SourceComputerToPing = GetParentManagementServer(TargetComputerToPing,SourceComputerToPing)
If Trim(SourceComputerToPing) = "" Then
SourceComputerToPing = "."
End If
For itmPing = 1 To intPingSamples
If bLogSuccessEvent = true Then
strMessage = "Executing Ping Number " &amp; CStr(itmPing)
call CreateEvent(EVENTID_LOGINFORMATION, EVENT_TYPE_INFORMATION, strMessage)
End If

boolPing = PingComputer(SourceComputerToPing, TargetComputerToPing)

If bLogSuccessEvent = true Then
strMessage = "Ping Number " &amp; CStr(itmPing) &amp; " Result: " &amp; CStr(boolPing)
call CreateEvent(EVENTID_LOGINFORMATION, EVENT_TYPE_INFORMATION, strMessage)
End If


If boolPing = True Then
Exit For
End If

If itmPing &lt; intPingSamples Then
Wscript.Sleep(intervalMilliseconds)
End If
Next
End If

call ReturnResponse(false, strMessage)

'---------------------------------------------------------------------------
' Retrieves the script output.
'---------------------------------------------------------------------------
Sub ReturnResponse(boolErrorFlag, strMessageToUse)
Dim intEventID, intEventType

If boolErrorFlag = true Then
oPropertyBag.AddValue "StatusCode", strStatusCode
oPropertyBag.AddValue "ResponseTime", strResponseTime
oPropertyBag.AddValue "ErrorMessage", strMessageToUse
intEventID = EVENTID_SCRIPT_ERROR
intEventType = EVENT_TYPE_ERROR
Else
oPropertyBag.AddValue "StatusCode", strStatusCode
oPropertyBag.AddValue "ResponseTime", strResponseTime
intEventID = EVENTID_SUCCESS
intEventType = EVENT_TYPE_INFORMATION

strMessageToUse = "The script '" &amp; SCRIPT_NAME &amp; "' completed successfully in " &amp; DateDiff("s", dtStart, Now) &amp; " seconds."

End If

If bLogSuccessEvent = true Then
call CreateEvent(intEventID, intEventType, strMessageToUse)
End If

Call oAPI.Return(oPropertyBag)
WScript.Quit
End Sub
'-------------------------------------------------
' Retrieves Parent management server of an agent
'-------------------------------------------------
Function GetParentManagementServer(agent,agentParent)

Dim resultFile, strFileText, objPath
Dim psScript
Dim oError, objShell, objReadFile , listofGateways, gatewayMachine ,boolPing , retSource
const DontShowWindow = 0, WaitUntilFinished = true
Set oError = New Error
boolPing = false
retSource=""
Set objShell = MomCreateObject("Wscript.Shell")

objPath = MomCreateObject("Scripting.FileSystemObject").GetParentFolderName(WScript.ScriptFullName)

resultFile = objPath &amp; "\" &amp; agent &amp; ".txt"
psScript = " $setupKey = Get-Item -Path 'HKLM:\Software\Microsoft\Microsoft Operations Manager\3.0\Setup';" &amp;_
" $installDirectory = $setupKey.GetValue('InstallDirectory') | Split-Path;" &amp;_
" $psmPath = $installdirectory + '\Powershell\OperationsManager\OperationsManager.psm1';" &amp;_
" $agentParent = '" &amp; agentParent &amp; "';" &amp;_
" Import-Module $psmPath;" &amp;_
" $agent = Get-SCOMAgent -Name '" &amp; agent &amp; "';" &amp;_
" if($agent -ne $null -and ($agent.GetPrimaryManagementServer()).IsGateway -eq $true) " &amp;_
" { (Get-SCOMAgent -Name '" &amp; agent &amp; "' | Get-SCOMParentManagementServer).Name | Out-File -FilePath '" &amp; resultFile &amp; "'; Exit 0;" &amp;_
" } else { $agentParent | Out-File -FilePath '" &amp; resultFile &amp; "'; Exit 0; } "

objShell.run "powershell.exe -command " &amp; psScript, DontShowWindow, WaitUntilFinished

On Error Resume Next
Set objReadFile = MomCreateObject("Scripting.FileSystemObject").OpenTextFile(resultFile, 1,True,-1)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
call CreateEvent(EVENTID_LOGINFORMATION,EVENT_TYPE_INFORMATION, oError.Description)
End If

If Not objReadFile.AtEndOfStream Then
strFileText = objReadFile.ReadAll
listofGateways = Split(strFileText , vbCrLf)
For Each gatewayMachine In listofGateways
If Trim(gatewayMachine) = "" Then
gatewayMachine = "."
End If
boolPing = PingComputer(".", Trim(gatewayMachine))
'this check is needed to verify whether a ping (initiated from Gateway or Management server) was successfully received from agent
if strStatusCode = "0" Then
retSource = Trim(gatewayMachine)
Exit For
End If
Next
End If

On Error Resume Next
objReadFile.Close
On Error Goto 0
Set objReadFile = Nothing
GetParentManagementServer = retSource

End Function


Sub CreateEvent(lEventID, lEventType, strMessage)
oAPI.LogScriptEvent SCRIPT_NAME,lEventID, lEventType, strMessage
End Sub

Function MomCreateObject(ByVal sProgramId)
Dim oError
Set oError = New Error

On Error Resume Next
Set MomCreateObject = CreateObject(sProgramId)
oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
call ReturnResponse(true, "Unable to create automation object '" &amp; sProgramId &amp; "'")
End If
End Function

'---------------------------------------------------------------------------
' Gets WMI Status.
'---------------------------------------------------------------------------
Function PingComputer(SourceComputerToPing, TargetComputerToPing)
Dim strFieldValues, strFieldVal, objFieldValues, boolStatus
Dim oError
Set oError = New Error
boolStatus = false
strStatusCode = "11003"
strResponseTime = "0"

On Error Resume Next

strFieldValues = ExecuteWMIQuery(SourceComputerToPing, "CIMv2", "SELECT StatusCode, ResponseTime FROM Win32_PingStatus WHERE Address = '" + TargetComputerToPing + "'", "StatusCode;ResponseTime")

If strFieldValues = ";;" Then
strStatusCode = "11003"
strResponseTime = "0"
Else
objFieldValues = Split(strFieldValues,";")
strStatusCode = objFieldValues(0)
strResponseTime = objFieldValues(1)

oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
boolStatus = false
strMessage = "Unable to parse WMI response '" &amp; strFieldValues &amp; "'"
call ReturnResponse(true, strMessage)
else
boolStatus = true
End If
End If

PingComputer = boolStatus
End Function

'---------------------------------------------------------------------------
' Retrieves a WMI object from the specified namespace.
'---------------------------------------------------------------------------
Function GetWMIObject(ByVal sNamespace)
Dim oWMI
Dim oError
Set oError = New Error

'get the object
on error resume next
set oWMI = GetObject(sNamespace)

oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
strMessage = "Unable to create automation object '" &amp; sNamespace &amp; "'"
call ReturnResponse(true, strMessage)
End If

'did it work?
If IsEmpty(oWMI) Then
'no
strMessage = "Error Number: " &amp; ObjError.number &amp; " Unable to open WMI Namespace '" &amp; sNamespace &amp; "'. Check to see if the WMI service is enabled and running, and ensure this WMI namespace exists."
call ReturnResponse(true, strMessage)
End if

set GetWMIObject = oWMI
End Function

'---------------------------------------------------------------------------
' Execute a WMI Query.
'---------------------------------------------------------------------------
Function ExecuteWMIQuery(TargetComputer, strBaseClass, strQuery, strPropertyNames)
Dim WbemSrv, WbemObjectSet, objItem, objPropertyNames, objProp, strPropValues
Dim oError
Set oError = New Error
strPropValues = ""

On Error Resume Next

Set WbemSrv = GetWMIObject("winmgmts:{impersonationLevel=impersonate}!\\" &amp; TargetComputer &amp; "\root\" &amp; strBaseClass)

Set WbemObjectSet = WbemSrv.ExecQuery(strQuery)

oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
strMessage = "Unable Execute Query '" &amp; strQuery &amp; "'"
call ReturnResponse(true, strMessage)
End If

objPropertyNames = Split(strPropertyNames,";")

oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
strMessage = "Unable Get Returned Values from Query '" &amp; strQuery &amp; "'"
call ReturnResponse(true, strMessage)
End If

For Each objItem in WbemObjectSet
For each objProp in objPropertyNames
If IsNUll(objItem.Properties_(objProp).value) = True Then
strPropValues = strPropValues &amp; "" &amp; ";"
Else
strPropValues = strPropValues &amp; CStr(objItem.Properties_(objProp).value) &amp; ";"
End If
Next
Next

oError.Save
On Error Goto 0

If oError.Number &lt;&gt; 0 Then
strMessage = "Unable Get Returned Values from Query '" &amp; strQuery &amp; "'"
call ReturnResponse(true, strMessage)
End If

ExecuteWMIQuery = strPropValues
End Function


Class Error
Private m_lNumber
Private m_sSource
Private m_sDescription
Private m_sHelpContext
Private m_sHelpFile
Public Sub Save()
m_lNumber = Err.number
m_sSource = Err.Source
m_sDescription = Err.Description
m_sHelpContext = Err.HelpContext
m_sHelpFile = Err.helpfile
End Sub
Public Sub Raise()
Err.Raise m_lNumber, m_sSource, m_sDescription, m_sHelpFile, m_sHelpContext
End Sub
Public Sub Clear()
m_lNumber = 0
m_sSource = ""
m_sDescription = ""
m_sHelpContext = ""
m_sHelpFile = ""
End Sub
Public Default Property Get Number()
Number = m_lNumber
End Property
Public Property Get Source()
Source = m_sSource
End Property
Public Property Get Description()
Description = m_sDescription
End Property
Public Property Get HelpContext()
HelpContext = m_sHelpContext
End Property
Public Property Get HelpFile()
HelpFile = m_sHelpFile
End Property
End Class
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="Probe"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
<InputType>System!System.BaseData</InputType>
</ProbeActionModuleType>