<DataSourceModuleType ID="AD_Replication_Partner_Op_Master_Consistency.DataSource" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:int"/>
<xsd:element name="TargetComputerName" type="xsd:string"/>
<xsd:element name="LogSuccessEvent" type="xsd:boolean"/>
<xsd:element name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="LogSuccessEvent" Selector="$Config/LogSuccessEvent$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterPropertyBagSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%windir%\system32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>//nologo $file/AD_Replication_Partner_Op_Master_Consistency.vbs$ $Config/TargetComputerName$ $Config/LogSuccessEvent$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>AD_Replication_Partner_Op_Master_Consistency.vbs</Name>
<Contents><Script>
'*************************************************************************
' Script Name - AD Replication Partner Op Master Consistency
'
' Purpose - Determines if each replication partner reports the same
' Op Master role master
'
' Assumptions - Script is run by a timed event
'
' Parameters - LogSuccessEvent - True/False value to indicates to log an
' an event for script success
' (useful for demos and debugging)
'
' (c) Copyright 2001, Microsoft Corporation, All Rights Reserved
' Proprietary and confidential to Microsoft Corporation
'*************************************************************************
Dim oAPI, oParams, oBag, bState
Dim oADOConn
bState=0
Set oAPI = CreateObject("Mom.ScriptAPI")
Err.Clear
Sub Main()
On Error Resume Next
Dim objAD, objPartner, objDC
Dim bLogSuccessEvent, dtStart
Dim strMessage, strComputer, strDC, strDnsDC, strAdsPath
Dim strMaster1, strMaster2
Dim strSourceDomain, strPartnerDomain
Dim bContinue
Dim oRootDSE, strConfig, strDomain, strSchema
' Other Variables
Dim TargetFQDNComputer, IsTargetAgentless
Set oParams = WScript.Arguments
if oParams.Count < 2 then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_ERROR, "The script '" & SCRIPT_NAME & _
"' failed to execute. Incorrect number of arguments"
Exit Sub
End if
' If the ComputerName passed in is in an FQDN format, cut it down to just the computer name
Dim nInStr
nInStr = InStr(TargetFQDNComputer, ".")
If 0 <> nInStr Then
TargetFQDNComputer = Left(TargetFQDNComputer, nInStr-1)
End If
Set oADOConn = CreateObject("ADODB.Connection")
If Err <> 0 Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_ERROR, "The script '" & SCRIPT_NAME & "' could not create object " & _
"'ADODB.Connection'. This is an unexpected error." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Sub
End If
oADOConn.Provider = "ADSDsOObject"
oADOConn.Open "ADs Provider"
If Err <> 0 Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_ERROR, "The script '" & SCRIPT_NAME & "' could not connect to the " & _
"object 'ADODB.Connection'. This is an unexpected error." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Sub
End If
If Not(IsTargetAgentless) Then
dtStart = Now
strComputer = TargetFQDNComputer
Set objAD = CreateObject("McActiveDir.ActiveDirectory")
objAD.Server = strComputer
strSourceDomain = objAD.GetDomainForDC(strComputer)
If objAD.RefreshReplicationPartners() Then
strAdsPath = objAD.NextReplicationPartner()
While strAdsPath <> ""
On Error Resume Next
Set objDC = objAD.BindObject(strAdsPath)
If (0 <> Err.Number) Or (Not(IsObject(objDC))) Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not bind to '" & strAdsPath & _
"'. " & vbCrLf & GetErrorString(Err.Number, Err.Description)
Else
' The DNS name and DC hostname of the replication partner
strDnsDC = LCase(objDC.Get("dNSHostName"))
strDC = LCase(objDC.Get("cn"))
Set objDC = Nothing
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not read required " & _
"fields from the object '" & strAdsPath & "'." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Sub
End If
' Bind to the local DC, because that is where we want to look up the naming contexts
Set oRootDSE = GetObject("LDAP://localhost/RootDSE")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not reach " & _
"the RootDSE on the localhost." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Sub
End If
' Get the naming contexts for config, domain, and schema
strConfig = oRootDSE.Get("ConfigurationNamingContext")
strDomain = oRootDSE.Get("DefaultNamingContext")
strSchema = oRootDSE.Get("SchemaNamingContext")
Set objPartner = CreateObject("McActiveDir.ActiveDirectory")
If (0 <> Err.Number) Or (Not(IsObject(objPartner))) Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not create object " & _
"'McActiveDir.ActiveDirectory'. This is an unexpected error." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Sub
End If
objPartner.Server = strDC
strPartnerDomain = objPartner.GetDomainForDC(strDC)
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the domain " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Else
' We only want to validate the PDC, Infrastructure, RID, and DomainNaming masters if the remote machine is in the
' same domain as we are
If strPartnerDomain = strSourceDomain Then
' PDC Master
Err.Clear
bContinue = True
' The FSMO role owner accoring to the local DC
strMaster1 = objAD.PDCMaster
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the PDC Op Master " & _
"for the DC '" & strComputer & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
Else
strMaster2 = GetOpMaster(strDnsDC, strDomain, "domainDNS")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the PDC Op Master " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
End If
End If
If bContinue Then
If strMaster1 <> strMaster2 Then
If strMaster1 = "" Then
strMessage = "Unable to determine PDC Op Master on domain controller '" & strComputer & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
If strMaster2 = "" Then
strMessage = "Unable to determine PDC Op Master on domain controller '" & strDC & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
strMessage = "Op Master PDC '" & strMaster1 & "' inconsistent with replication partner '" & strDnsDC & "' '" & strMaster2 & "'."
CreateEvent EVENTID_OP_MASTERS_INCONSISTENT, EVENT_TYPE_WARNING, strMessage
End If
End If
Else
If bLogSuccessEvent Then
strMessage = "Op Master PDC '" & strMaster1 & "' consistent with replication partner '" & strDnsDC & "'."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
' RID Master
Err.Clear
bContinue = True
strMaster1 = objAD.RIDMaster
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the RID Op Master " & _
"for the DC '" & strComputer & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
Else
strMaster2 = GetOpMaster(strDnsDC, strDomain, "rIDManager")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the RID Op Master " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
End If
End If
If bContinue Then
If strMaster1 <> strMaster2 Then
If strMaster1 = "" Then
strMessage = "Unable to determine RID Op Master on domain controller '" & strComputer & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
If strMaster2 = "" Then
strMessage = "Unable to determine RID Op Master on domain controller '" & strDC & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
strMessage = "Op Master RID '" & strMaster1 & "' inconsistent with replication partner '" & strDnsDC & "' '" & strMaster2 & "'."
CreateEvent EVENTID_OP_MASTERS_INCONSISTENT, EVENT_TYPE_WARNING, strMessage
End If
End If
Else
If bLogSuccessEvent Then
strMessage = "Op Master RID '" & strMaster1 & "' consistent with replication partner '" & strDnsDC & "'."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
strMaster1 = objAD.InfrastructureMaster
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Infrastructure Op Master " & _
"for the DC '" & strComputer & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
Else
strMaster2 = GetOpMaster(strDnsDC, strDomain, "infrastructureUpdate")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Infrastructure Op Master " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
End If
End If
If bContinue Then
If strMaster1 <> strMaster2 Then
If strMaster1 = "" Then
strMessage = "Unable to determine infrastructure Op Master on domain controller '" & strComputer & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
If strMaster2 = "" Then
strMessage = "Unable to determine infrastructure Op Master on domain controller '" & strDC & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
strMessage = "Op Master infrastructure '" & strMaster1 & "' inconsistent with replication partner '" & strDnsDC & "' '" & strMaster2 & "'."
CreateEvent EVENTID_OP_MASTERS_INCONSISTENT, EVENT_TYPE_WARNING, strMessage
End If
End If
Else
If bLogSuccessEvent Then
strMessage = "Op Master infrastructure '" & strMaster1 & "' consistent with replication partner '" & strDnsDC & "'."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
End If
End If
' Schema Master
Err.Clear
bContinue = True
strMaster1 = objAD.SchemaMaster
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Schema Op Master " & _
"for the DC '" & strComputer & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
Else
strMaster2 = GetOpMaster(strDnsDC, strSchema, "dMD")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Schema Op Master " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
End If
End If
If bContinue Then
If strMaster1 <> strMaster2 Then
If strMaster1 = "" Then
strMessage = "Unable to determine schema Op Master on domain controller '" & strComputer & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
If strMaster2 = "" Then
strMessage = "Unable to determine schema Op Master on domain controller '" & strDC & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
strMessage = "Op Master schema '" & strMaster1 & "' inconsistent with replication partner '" & strDnsDC & "' '" & strMaster2 & "'."
CreateEvent EVENTID_OP_MASTERS_INCONSISTENT, EVENT_TYPE_WARNING, strMessage
End If
End If
Else
If bLogSuccessEvent Then
strMessage = "Op Master schema '" & strMaster1 & "' consistent with replication partner '" & strDnsDC & "'."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
' Domain Naming Master
Err.Clear
bContinue = True
strMaster1 = objAD.DomainNamingMaster
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Domain Naming Op Master " & _
"for the DC '" & strComputer & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
Else
strMaster2 = GetOpMaster(strDnsDC, strConfig, "crossRefContainer")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' could not " & _
"determine the Domain Naming Op Master " & _
"for the DC '" & strDC & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
bContinue = False
End If
End If
If bContinue Then
If strMaster1 <> strMaster2 Then
If strMaster1 = "" Then
strMessage = "Unable to determine domain naming Op Master on domain controller '" & strComputer & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
If strMaster2 = "" Then
strMessage = "Unable to determine domain naming Op Master on domain controller '" & strDC & "'."
CreateEvent EVENTID_CANT_DETERMINE_OP_MASTER, EVENT_TYPE_ERROR, strMessage
Else
strMessage = "Op Master domain naming '" & strMaster1 & "' inconsistent with replication partner '" & strDnsDC & "' '" & strMaster2 & "'."
CreateEvent EVENTID_OP_MASTERS_INCONSISTENT, EVENT_TYPE_WARNING, strMessage
End If
End If
Else
If bLogSuccessEvent Then
strMessage = "Op Master domain naming '" & strMaster1 & "' consistent with replication partner '" & strDnsDC & "'."
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
Set objPartner = Nothing
Err.Clear
End If
strAdsPath = objAD.NextReplicationPartner()
Wend
if bState=0 then
set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "GOOD"
oBag.AddValue "EventID", EVENTID_GOOD
oAPI.AddItem oBag
END IF
if bState=1 then
set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "BAD"
oBag.AddValue "EventID", EVENTID_BAD
oAPI.AddItem oBag
END IF
oAPI.ReturnItems
If bLogSuccessEvent Then
CreateEvent EVENTID_SUCCESS, EVENT_TYPE_INFORMATION, "The script '" & SCRIPT_NAME & "' completed in " & _
DateDiff("s", dtStart, Now) & " seconds."
End If
Else
strMessage = "An error occurred." & vbCrLf & _
"Error: Could not get list of replication partners."
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_ERROR, strMessage
End If
Set objAD = Nothing
Else
CreateEvent EVENT_ID_AGENTLESS, EVENT_TYPE_ERROR, "The AD Management Pack does not support the agentless management mode." & vbCrLf & _
"The script '" & SCRIPT_NAME & "' will not execute." & vbCrLf & _
"To prevent this alert being generated again, either change the monitoring " & _
"mode of the computer '" & TargetFQDNComputer & "' to agent-managed " & _
"or disable the rule that generated this alert."
End If
End Sub
'******************************************************************************
' Name: GetOpMaster
'
' Purpose: Get the Operational Master DNS name for a particular FSMO role by
' querying a specific DC
'
' Parameters: strDnsDC, The name of the DC to be queried
' strNC, The naming context to query
' strObjClass, The specific objectClass of the fSMORoleOwner
'
' Return: The DNS name of the DC holding the FSMO role
'
Function GetOpMaster(strDnsDC, strNC, strObjClass)
Dim strQuery, rsResult, oTemp, oPartner
On Error Resume Next
' Attempt to get the FSMO role owner by querying the remote machine
strQuery = "<LDAP://" & strDnsDC & "/" & strNC & ">;(&(objectClass=" & strObjClass & ")(fSMORoleOwner=*));fSMORoleOwner;Subtree"
Set rsResult = oADOConn.Execute(strQuery)
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' failed to execute" & _
"the following LDAP query: '" & strQuery & "'. " & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Function
End If
rsResult.MoveFirst
' This will return the NTDS Settings object of the partner. Get the parent of the object, then look at the dNSHostName field
Set oTemp = GetObject("LDAP://" & strDnsDC & "/" & rsResult("fSMORoleOwner"))
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' failed to get " & _
"the fSMORoleOwner for '" & strDnsDC & "'." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Function
End If
Set oPartner = GetObject(oTemp.Parent)
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' failed to get " & _
"the fSMORoleOwner parent object for '" & strDnsDC & "'." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Function
End If
GetOpMaster = oPartner.Get("dNSHostName")
If 0 <> Err Then
CreateEvent EVENTID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" & SCRIPT_NAME & "' failed to get " & _
"the dNSHostName for '" & strDnsDC & "'." & _
vbCrLf & GetErrorString(Err.Number, Err.Description)
Exit Function
End If
Set rsResult = Nothing
End Function
'******************************************************************************
' Name: CreateEvent
'
' Purpose: Creates a MOM event
'
' Parameters: lngEventID, the ID for the event
' lngEventType, the severity for the event. See constants at head of file
' strMessage, the message for the event
'
' Return: nothing
'
Sub CreateEvent(lngEventID, lngEventType, strMessage)
oAPI.LogScriptEvent "AD Replication Partner Op Master Consistency", lngEventID, lngEventType, strMessage
if lngEventID=EVENTID_CANT_DETERMINE_OP_MASTER or lngEventID=EVENTID_OP_MASTERS_INCONSISTENT then
bState=1
end if
End Sub
'******************************************************************************
' Name: GetErrorString
'
' Purpose: Attempts to find the description for an error if no description
' is passed in.
'
' Parameters: lErrNumber, the error number
' strErrDescription, the error description (if known)
'
' Return: String, the description for the error. (Includes the error code.)
'
Function GetErrorString(lErrNumber, strErrDescription)
On Error Resume Next
If 0 >= Len(strErrDescription) Then
' If we don't have an error description, then check to see if the error
' is a 0x8007xxxx error. If it is, then look it up.
Const ErrorMask = &HFFFF0000
Const HiWord8007 = &H80070000
Const LoWordMask = 65535 ' This is equivalent to 0x0000FFFF
If (lErrNumber And ErrorMask) = HiWord8007 Then
Dim oShell
Set oShell = CreateObject("WScript.Shell")
If IsObject(oShell) Then
Dim oExec
Set oExec = oShell.Exec("net helpmsg " & (lErrNumber And LoWordMask))
Dim strMessage, i
Do
strMessage = oExec.stdout.ReadLine()
i = i + 1
Loop While (Len(strMessage) = 0) And (i < 5)
strErrDescription = strMessage
End If
End If
End If
GetErrorString = "The error returned was '" & strErrDescription & "' (0x" & Hex(lErrNumber) & ")"
End Function