DPM Service Discovery

DPM_Service_Discovery (WriteActionModuleType)

Run service discovery for DPM computers and protected servers

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
InputTypeSystem.BaseData
Comment{44470B78-DB1B-4FC5-BBA9-AF6CD12DC5C9}

Member Modules:

ID Module Type TypeId RunAs 
RunScriptAction WriteAction System.Mom.BackwardCompatibility.ScriptResponse Default

Source Code:

<WriteActionModuleType ID="DPM_Service_Discovery" Accessibility="Internal" Comment="{44470B78-DB1B-4FC5-BBA9-AF6CD12DC5C9}">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>MomBackwardCompatibility!System.Mom.BackwardCompatibility.AlertGenerationSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="AlertGeneration" type="AlertGenerationType"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="InvokerType" type="xsd:integer"/>
</Configuration>
<ModuleImplementation>
<Composite>
<MemberModules>
<WriteAction ID="RunScriptAction" TypeID="MomBackwardCompatibility!System.Mom.BackwardCompatibility.ScriptResponse">
<AlertGeneration>$Config/AlertGeneration$</AlertGeneration>
<InvokerType>$Config/InvokerType$</InvokerType>
<Body><Script>
'-------------------------------------------------------------------
' &lt;company&gt;Microsoft Corporation&lt;/company&gt;
' &lt;copyright&gt;Copyright (c) Microsoft Corporation 2003&lt;/copyright&gt;
' &lt;summary&gt;
' Service discovery for DPM servers and servers protected by DPS
' &lt;/summary&gt;
'-------------------------------------------------------------------

Option Explicit

' Constants

' Standard Event ID for script failure
Const EVENT_ID_SCRIPT_FAILURE = 40000
Const EVENT_ID_SERVICE_CRASH = 30500
Const EVENT_ID_DATABASE_CRASH = 30501
Const EVENT_ID_SERVICE_SUCCESS = 30502
Const EVENT_ID_DATABASE_SUCCESS = 30503

'Event log event severity
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

'MOM Alert severity
Const MOMALERT_SEVERITY_CRITICALERROR = 50
Const MOMALERT_SEVERITY_WARNING = 30
Const MOMALERT_SEVERITY_INFORMATION = 20

'Problem state constants
Const ALERT_PROBLEM_STATE_ACTIVE = 3
Const ALERT_PROBLEM_STATE_INACTIVE = 1
Const EVENT_CATEGORY_ACTIVE = 1
Const EVENT_CATEGORY_INACTIVE = 2

'Event field order
Const ALERT_PROBLEM_RECOMMENDEDACTION = "$1"
Const ALERT_COMPUTERNAME = "$2"
Const ALERT_NAME = "$3"
Const ALERT_ROLE = "$4"
Const ALERT_COMPONENT = "$5"
Const ALERT_INSTANCE = "$6"

'Event parameter
Const gEVENT_PARAMETER_DESCRIPTION = 1

'Name used for the state variable used to hold context for DPM MOM script
Const strDPSProductionServerList = "DPSProductionServers"
'Name used for error reporting
Const strProductNameForError = "Data Protection Manager"

'DPM Meta model constants
Const strServerDiscoveryScopeFilter = "ComputerName"
Const strDPSRole = "DPM"
Const strDPSComponentPrimaryKey = "Name"
Const strDPSComponentHeartbeat = "HeartBeat"
Const strDPSComponentDatabase = "Database"
Const strDPSComponentPerf = "Performance"
Const strDPSComponentOther = "Other"

'Constants for hearbeat and connectivity alerts
Dim strDPSDatabaseAlertDescription,strDPSHearbeatAlertDescription
strDPSDatabaseAlertDescription = "The DPM database is not available."&amp; vbNewLine &amp; _
vbNewLine &amp; vbNewLine &amp; "DPM ID:75653C2D-EC0F-4cd4-8189-B416017DB965:0"
Const strDPSDatabaseAlertName = "DPM Database Not Available"
strDPSHearbeatAlertDescription = "The DPM service has failed." &amp; vbNewLine &amp; _
vbNewLine &amp; vbNewLine &amp; "DPM ID:75653C2D-EC0F-4cd4-8189-B416017DB965:0"
Const strDPSHearbeatAlertName = "DPM Service Not Available"

'Event descriptions
Const strDPSServiceDiscoveryComputerDiscoveryEventDescription = "DPM service discovery has updated the list of protected servers."
Const strDPSHeartbeatFailureEventDescription = "During the past 30 minutes, MOM has failed to confirm the completion of any jobs on the DPM computer. This may be due to a failure of the DPM service or a database failure."
Const strDPSHeartbeatSuccessEventDescription = "During the past 30 minutes, MOM has confirmed the completion of at least one job on the DPM computer."

'PS Meta Model constants
Const strPSRole = "DPM Protected"
Const strPSComponentPrimaryKey = "Volume/Computer"
Const strPSComponentReplica = "Replica"
Const strPSComponentShadowCopy = "Shadow Copies"
Const strPSComponentConnectivity = "Connectivity"
Const strPSComponentRecovery = "Recovery"

'Database related constants
Const strConnectionString = "integrated security=SSPI;Provider=SQLOLEDB; Data Source=(local)\MICROSOFT$DPM$;Initial Catalog=DPMDB;"
Const strProcedureDataSource = "prc_MOM_DataSource_Get"
Const strProcedureProductionServer = "prc_MOM_ProductionServer_Get"
Const strProcedureHeartbeat = "prc_MOM_Heartbeat_Get"
Const strProcedureParamServerName = "@ServerName"
Const strDbParamPS = "ServerName"
Const boolDbParamAgentDeleted = "Deleted"
Const strDbParamVolume = "Volume"
Const strDbParamReturnValue = "@RETURN_VALUE"
Const strDbParamConnectivityJobCount = "JobCount"

'ADO Constants
Const intADONVarChar = 202
Const intADOInt = 3
Const intADOParamInput = 1
Const intADOParamReturnValue = 4
Const intADOCmdStoredProc = 4

'=============
' Method: CreateStoredProcedure
' Description: Create a command to execute a stored procedure. Adds the return value as an argument for the command
' Arguments
' strProcName - Name of the stored procedure
' objCommand - ADO command
' objConnection - ADO connection
'=============
Sub CreateStoredProcedure(strProcName,objCommand,objConnection)
Dim returnParam

set objCommand = CreateObject("ADODB.Command")
set returnParam = objCommand.CreateParameter(strDbParamReturnValue,intADOInt, intADOParamReturnValue)
objCommand.Parameters.Append returnParam
With objCommand
Set .ActiveConnection = objConnection
.CommandText = strProcName
.CommandType = intADOCmdStoredProc
End With
End Sub

'=============
' Method: ValidateStoredProcedureReturnValue
' Description: Validate the return value of the stored procedure
' Arguments
' objCommand - ADO command
' strProcedureName - Name of the stored procedure
'=============
Sub ValidateStoredProcedureReturnValue(objCommand,strProcedureName)
Dim returnVal
returnVal = objCommand.Parameters(strDbParamReturnValue).Value
'If we are returning custom error values this will not work
If (returnVal &lt;&gt;0) Then
ThrowScriptError returnVal, strProcedureName
End If
End Sub

'=============
' Method: Trace
' Description: Trace to the MOM Log.
' Uses the strComponent defined globally for the file
'=============
Sub Trace(strMessage)
On Error Resume Next
Dim strMsg
strMsg = strComponent &amp; ": " &amp; strMessage
ScriptContext.Echo strMsg
End Sub

'=============
' Method: ThrowScriptError
' Description: Creates an event and sends it back to the mom server
'This triggers a 'MOM' MOM pack rule which displays an error to the user
'Execution of the script stops after the event is created
'=============

Sub ThrowScriptError(intErrorCode,strErrorDescription)
On Error Resume Next
Dim objScriptErrorEvent

Set objScriptErrorEvent = ScriptContext.CreateEvent()
With objScriptErrorEvent
.EventNumber = EVENT_ID_SCRIPT_FAILURE
.EventType = EVENT_TYPE_ERROR
.Message = strVbError
.SetEventParameter strProductNameForError
.SetEventParameter intErrorCode 'Error Event
.SetEventParameter strErrorDescription 'Error description
.SetEventParameter intErrCode
End With
ScriptContext.Submit objScriptErrorEvent
ScriptContext.Quit
End Sub

'=============
' Method: Create a MOM Alert
' If the Role is empty it means it is a stateless alert and there is no need to set the role,component,instane and problem state
'=============

Sub CreateAlert (objAlert,alertLevel,strComputer,strDomain,strAlertSource,strAlertDescription,strAlertName,strRole,strComponent,strInstance,intProblemState)
Set objAlert = ScriptContext.CreateAlert()
objAlert.AlertLevel = alertLevel
objAlert.Computer = strComputer
objAlert.ComputerDomain = strDomain
objAlert.AlertSource = strAlertSource
objAlert.Description = strAlertDescription
objAlert.Name = strAlertName
If (Len(strRole) &lt;&gt; 0) Then
objAlert.ServerRole = strRole
objAlert.Component = strComponent
objAlert.ServerRoleInstance = strInstance
objAlert.ProblemState = intProblemState
End If
End Sub

'=============
' Method: Create and submit a MOM Alert
'=============
Sub CreateAndSubmitAlert (objAlert,alertLevel,strComputer,strDomain,strAlertSource,strAlertDescription,strAlertName,strRole,strComponent,strInstance,intProblemState)
CreateAlert objAlert,alertLevel,strComputer,strDomain,strAlertSource,strAlertDescription,strAlertName,strRole,strComponent,strInstance,intProblemState
ScriptContext.Submit objAlert
End Sub

'=============
' Method: Create a MOM Event
'=============
Sub CreateEvent (intEventSeverity,strMessage,strComputer,strDomain,intEventNumber)
Dim objEvent
Trace "Creating event " &amp; intEventNumber
Set objEvent = ScriptContext.CreateEvent()
With objEvent
.EventType = intEventSeverity
.Message = strMessage
.LoggingComputer = strComputer
.LoggingDomain = strDomain
.EventNumber = intEventNumber
End With
ScriptContext.Submit objEvent
End Sub

'Component for tracing
Const strComponent = "DPM Service discovery"

'=============
' Method: Main
' Description: The Sub called by MOM Runtime (with ScriptContext object)
'=============
Sub Main()
On Error Resume Next
Trace "Starting Service discovery"
'Service Discovery for the DPM server
Call DPSServiceDiscovery()
If (Err.number &lt;&gt; 0) Then
ThrowScriptError Err.number, Err.Description
End If

'Service Discovery for PS
Call PSServiceDiscovery()
If (Err.number &lt;&gt; 0) Then
ThrowScriptError Err.number, Err.Description
End If
Trace "Finished Service discovery"
End Sub


'=============
' Method: DPSServiceDiscovery
' Description: Discover the instances,components for the DPM role
'=============
Sub DPSServiceDiscovery()
Dim objDiscData
Dim objCollection
Dim objInstance

Trace "Starting Service discovery for DPM role"
'Create the discovery data object
Set objDiscData = ScriptContext.CreateDiscoveryData

'Create the collection for this server
Set objCollection = objDiscData.CreateCollection
objCollection.ClassID = strDPSRole
'It is important to have the computer in the format NetbiosDomain\NetbiosComputer
objCollection.AddScopeFilter strServerDiscoveryScopeFilter,scriptContext.TargetNetbiosDomain &amp; "\" &amp; ScriptContext.TargetNetbiosComputer
objCollection.AddScopeComponent strDPSComponentHeartbeat
objCollection.AddScopeComponent strDPSComponentDatabase
objCollection.AddScopeComponent strDPSComponentPerf
objCollection.AddScopeComponent strDPSComponentOther

'Create an instance for this DPM Server
Set objInstance = objCollection.CreateInstance
objInstance.AddKeyProperty strDPSComponentPrimaryKey,ScriptContext.TargetNetbiosComputer
objInstance.AddComponent strDPSComponentHeartbeat
objInstance.AddComponent strDPSComponentDatabase
objInstance.AddComponent strDPSComponentPerf
objInstance.AddComponent strDPSComponentOther

'Add the instance to the collection
objCollection.AddInstance objInstance

'Add the collection to service discovery data
objDiscData.AddCollection objCollection

'Submit the data
ScriptContext.Submit objDiscData
Trace "Finished Service discovery for DPM role"
End Sub


'=============
' Method: PSServiceDiscovery
' Description: Discover the instances,components for the PS role (DPS Protected)
'=============
Sub PSServiceDiscovery()
Dim objDiscData
Dim objCollection
Dim objConnection
Dim objSrvCommand
Dim objSrvRecordSet
Dim strComputerName
Dim returnParam
Dim returnVal
Dim boolEmpty
Dim boolAgentDeleted
Dim objConnectivityInstance
'We wait these many secs after we have raised the event for it to go thru
'If the event and service discovery get reordered the computer will get blocked
Const intSDSleepTime = 10000 '10 secs

Trace "Starting Service discovery for PS role"
'Service discovery collection is empty
boolEmpty = true


'Create the AODB object
Set objConnection = CreateObject("ADODB.Connection")

'Open the db connection
objConnection.Open strConnectionString

'Create the service discovery data object
Set objDiscData = ScriptContext.CreateDiscoveryData

'Create the record set to retrieve the servernames
CreateStoredProcedure strProcedureProductionServer,objSrvCommand,objConnection
set objSrvRecordSet=objSrvCommand.execute

Do Until objSrvRecordSet.EOF
'Get the name of the computer
strComputerName = objSrvRecordSet(strDbParamPS)
boolAgentDeleted = objSrvRecordSet(boolDbParamAgentDeleted)
Trace "Starting Service discovery for " &amp; strComputerName
Trace "AgentDeleted is " &amp; boolAgentDeleted

'Prepare the service discovery collection for this server
Set objCollection = objDiscData.CreateCollection

'Create an event so that MOM knows about this computer
CreateComputerDiscoveryEvent strComputerName

'Build the scope for this service discovery
BuildCollectionScopeForPS objCollection,strComputerName

'Discover the datasources for this computer
DiscoverDataSources strComputerName,boolAgentDeleted,objConnection,objCollection

'Add the collection associated with this server
'Note that if we didn't find any data sources we still submit this empty
'collection so that MOM will remove the old instances for this server
objDiscData.AddCollection objCollection
objSrvRecordSet.MoveNext
'Service discovery collection is no longer empty
boolEmpty = false
Loop
'Clean up
objSrvRecordSet.Close
set objSrvRecordSet = Nothing

ValidateStoredProcedureReturnValue objSrvCommand, strProcedureDataSource
set objSrvCommand = Nothing
objConnection.Close
set objConnection = Nothing

'Submit the service discovery data
if(NOT boolEmpty) Then
ScriptContext.Sleep intSDSleepTime
ScriptContext.Submit objDiscData
End if
Trace "Finished Service discovery for PS role"
End Sub

'=============
' Method: DiscoverDataSources
' Description: Discover the protected data sources associated with this computer
' Arguments
' strComputerName - Name of the computer
' objConnection - database connection
' objCollection - service discovery collection
'=============
Sub DiscoverDataSources(strComputerName,boolAgentDeleted,objConnection,objCollection)
Dim param
Dim objDataSourceCommand
Dim objDataSourceRecordSet
Dim strDataSource
Dim objInstance
Dim returnVal
Dim boolDataSourceFound

'This server doesn't have any data sources yet
boolDataSourceFound = false

Trace "Discovering data sources for computer " &amp; strComputerName
'Execute the stored procedure to retrieve list of datasources for each PS
CreateStoredProcedure strProcedureDataSource,objDataSourceCommand,objConnection
set param = objDataSourceCommand.CreateParameter(strProcedureParamServerName,intADONVarChar, intADOParamInput,16)
objDataSourceCommand.Parameters.Append param
objDataSourceCommand.Parameters(strProcedureParamServerName).Value = strComputerName
set objDataSourceRecordSet = objDataSourceCommand.Execute

Do Until objDataSourceRecordSet.EOF
'Retrieve the name of the data source
strDatasource = objDataSourceRecordSet(strDbParamVolume)

Trace "Added instance " &amp; strDatasource

'Create an instance of the dps protected role
Set objInstance = objCollection.CreateInstance
BuildInstanceForPS objInstance,strDataSource

'Add to the collection
objCollection.AddInstance objInstance

set objInstance = Nothing
objDataSourceRecordSet.MoveNext
boolDataSourceFound = true
Loop

If (boolDataSourceFound OR (boolAgentDeleted = false)) Then
'Create an instance for connectivity/recovery if this server has active data sources
' or it has an agent installed
Set objInstance = objCollection.CreateInstance
objInstance.AddKeyProperty strPSComponentPrimaryKey,strComputerName
objInstance.AddComponent strPSComponentConnectivity
objInstance.AddComponent strPSComponentRecovery
objCollection.AddInstance objInstance
set objInstance = Nothing
End if

'Clean up
objDataSourceRecordSet.Close
set objDataSourceRecordSet = Nothing

ValidateStoredProcedureReturnValue objDataSourceCommand ,strProcedureDataSource
set objDataSourceCommand = Nothing
Trace "Finished Discovering data sources for computer " &amp; strComputerName
End Sub


'=============
' Method: BuildCollectionScopeForPS
' Description: Build the scope for service discovery
' Arguments
' objCollection - Service discovery collection
' strComputerName - name of the computer for which we are doing service discovery
'=============
Sub BuildCollectionScopeForPS(objCollection,strComputerName)
objCollection.ClassID = strPSRole
'It is important to have the full name here in the form DOMAIN\COMPUTER
objCollection.AddScopeFilter strServerDiscoveryScopeFilter,scriptContext.TargetNetbiosDomain &amp; "\" &amp; strComputerName
objCollection.AddScopeComponent strPSComponentReplica
objCollection.AddScopeComponent strPSComponentShadowCopy
objCollection.AddScopeComponent strPSComponentConnectivity
objCollection.AddScopeComponent strPSComponentRecovery
End Sub

'=============
' Method: BuildInstanceForPS
' Description: Create an instance for service discovery
' Arguments
' objInstance - Service discovery Instance
' strDataSource - name of the data source for which we are building instances
'=============
Sub BuildInstanceForPS(objInstance,strDataSource)
objInstance.AddKeyProperty strPSComponentPrimaryKey,strDataSource
'Add the replica and shadow copy components for this instance
objInstance.AddComponent strPSComponentReplica
objInstance.AddComponent strPSComponentShadowCopy
End Sub

'=============
' Method: CreateComputerDiscoveryEvent
' Description: Create an event for this computer so that it added to the
' computer table in MOM. This needs to be done before we run service
' discovery for the computer
'=============

Sub CreateComputerDiscoveryEvent (strComputerName)
Dim objEvent
Set objEvent = ScriptContext.CreateEvent
objEvent.EventType = EVENT_TYPE_INFORMATION
objEvent.LoggingComputer = strComputerName
objEvent.Message = strDPSServiceDiscoveryComputerDiscoveryEventDescription
objEvent.LoggingDomain = ScriptContext.TargetNetbiosDomain
ScriptContext.Submit objEvent
End Sub

</Script></Body>
<Language>VBScript</Language>
<Name>DPM Service Discovery</Name>
<Parameters/>
<ManagementPackId>[Microsoft.SystemCenter.DPM,,1.0.0.1]</ManagementPackId>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="RunScriptAction"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>SystemLibrary!System.BaseData</InputType>
</WriteActionModuleType>