Origine dati script AD Replication Partner Count

AD_Replication_Partner_Count.DataSource (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.PropertyBagData

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource System.CommandExecuterPropertyBagSource Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Intervallo (secondi)
LogSuccessEventstring$Config/LogSuccessEvent$Evento di registrazione riuscita
ConnectionsThresholdWarningstring$Config/ConnectionsThresholdWarning$Avviso soglia connessioni
ConnectionsThresholdErrorstring$Config/ConnectionsThresholdError$Errore soglia connessioni
TimeoutSecondsint$Config/TimeoutSeconds$Timeout in secondi

Source Code:

<DataSourceModuleType ID="AD_Replication_Partner_Count.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="ConnectionsThresholdWarning" type="xsd:string"/>
<xsd:element name="ConnectionsThresholdError" type="xsd:string"/>
<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="ConnectionsThresholdWarning" Selector="$Config/ConnectionsThresholdWarning$" ParameterType="string"/>
<OverrideableParameter ID="ConnectionsThresholdError" Selector="$Config/ConnectionsThresholdError$" 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_Count.vbs$ $Config/TargetComputerName$ $Config/LogSuccessEvent$ $Config/ConnectionsThresholdWarning$ $Config/ConnectionsThresholdError$ $Target/Property[Type="AD2008Core!Microsoft.Windows.Server.2008.AD.DomainControllerRole"]/IsRODC$ </CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>AD_Replication_Partner_Count.vbs</Name>
<Contents><Script>
'*************************************************************************
' Script Name - AD Replication Partner Count
'
' Purpose - Checks to make sure a DC is not on a replication island,
' and that the number of inbound and outbound connections
' are within reasonable limits.
'
' Assumptions - Script is run by a timed event
'
' Parameters - LogSuccessEvent - Indicates whether to log an event when
' the script completes successfully (that is without
' logging any errors)
' ConnectionsThresholdWarning - If the number of connections
' (either inbound or outbound) is greater than this
' number then an alert, of severity warning, is raised.
' ConnectionsThresholdError - If the number of connections
' (either inbound or outbound) is greater than this
' number then an alert, of severity error, is raised.
'
' (c) Copyright 2001, Microsoft Corporation, All Rights Reserved
' Proprietary and confidential to Microsoft Corporation
'*************************************************************************

Option Explicit

'Event Constants
Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_ERROR = 1
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_INFORMATION = 4

' Event IDs
Const EVENT_ID_INVALID_PARAMETER = 66
Const EVENT_ID_REPLICATION_ISLAND = 80
Const EVENT_ID_TOO_MANY_CONNECTIONS = 81
Const EVENT_ID_SUCCESS = 99
Const EVENT_ID_SCRIPT_ERROR = 1000
Const EVENT_ID_AGENTLESS = 98

CONST EVENT_ID_FAILED = 18920
CONST EVENT_ID_WARNING = 18921
CONST EVENT_ID_SUCCEEDED = 1080
'Other constants
Const SCRIPT_NAME = "AD Replication Partner Count"

' Limits, as defined by the Active Directory Best practices.
' The MAX_CONNECTIONS constant is defined as 1175 because Active Directory triggers Warning event ID=1870 if a Domain Controller has more than 1175 replication partners.
Const MAX_CONNECTIONS = 1175
Const MIN_CONNECTIONS = 1

' TypedPropertyBag
const PerformanceDataType = 2
const StateDataType = 3

Dim oAPI, oParams, oBag, oReg
Set oAPI = CreateObject("Mom.ScriptAPI")
oReg=null
Err.Clear

Dim bAddItem, nState

bAddItem=true
nState=0

Sub Main()
On Error Resume Next

Dim iOutboundConnections
Dim bInterSiteConnectionExists

' Other Variables
Dim dtStart, lWarningThreshold, lErrorThreshold, strInvalidParams, TargetFQDNComputer, bLogSuccess, IsTargetAgentless, bIsRODC
Set oParams = WScript.Arguments
if oParams.Count &lt; 5 Then
Wscript.Echo "Incorrect number of arguments!"
Wscript.Quit -1
End if

TargetFQDNComputer = oParams(0)
bLogSuccess = CBool(oParams(1))
lWarningThreshold = CLng(oParams(2))
lErrorThreshold = CLng(oParams(3))
bIsRODC = CBool(oParams(4))
IsTargetAgentless = False
Err.Clear

If Not(IsTargetAgentless) Then
dtStart = Now

If (MIN_CONNECTIONS &gt; lWarningThreshold) Or (MAX_CONNECTIONS &lt; lWarningThreshold) Then
strInvalidParams = strInvalidParams &amp; "ConnectionsThresholdWarning must be between " &amp; MIN_CONNECTIONS &amp; " and " &amp; MAX_CONNECTIONS &amp; "." &amp; vbCrLf &amp; _
"The current value of ConnectionsThresholdWarning is " &amp; _
lWarningThreshold &amp; "." &amp; vbCrLf &amp; _
"ConnectionsThresholdWarning will be set to 20 for " &amp; _
"this execution of this script." &amp; vbCrLf
lWarningThreshold = 20
End If
If (lErrorThreshold &lt; lWarningThreshold) Then
strInvalidParams = strInvalidParams &amp; "ConnectionsThresholdError must not be less than " &amp; _
"ConnectionsThresholdWarning." &amp; vbCrLf &amp; _
"The current value of ConnectionsThresholdError is " &amp; _
lErrorThreshold &amp; "." &amp; vbCrLf &amp; _
"The current value of ConnectionsThresholdWarning is " &amp; _
lWarningThreshold &amp; "." &amp; vbCrLf &amp; _
"ConnectionsThresholdError will be set to " &amp; lWarningThreshold &amp; _
" for this execution of this script." &amp; vbCrLf
lErrorThreshold = lWarningThreshold
End If
If (MIN_CONNECTIONS &gt; lErrorThreshold) Or (MAX_CONNECTIONS &lt; lErrorThreshold) Then
Dim lOriginalThreshold
lOriginalThreshold = lErrorThreshold
If lWarningThreshold &gt; 30 Then
lErrorThreshold = lWarningThreshold
Else
lErrorThreshold = 30
End If
strInvalidParams = strInvalidParams &amp; "ConnectionsThresholdError must be between " &amp; MIN_CONNECTIONS &amp; " and " &amp; MAX_CONNECTIONS &amp; "." &amp; vbCrLf &amp; _
"The current value of ConnectionsThresholdError is " &amp; _
lOriginalThreshold &amp; "." &amp; vbCrLf &amp; _
"ConnectionsThresholdError will be set to " &amp; lErrorThreshold &amp; _
" for this execution of this script." &amp; vbCrLf
End If

If 0 &lt; Len(strInvalidParams) Then
bAddItem=false
CreateEvent EVENT_ID_INVALID_PARAMETER, EVENT_TYPE_WARNING, "The script '" &amp; SCRIPT_NAME &amp; _
"' detected one or more invalid parameters." &amp; _
vbCrLf &amp; vbCrLf &amp; strInvalidParams &amp; vbCrLf &amp; vbCrLf &amp; _
"To correct the error, find the rule 'Script - " &amp; _
SCRIPT_NAME &amp; "' and from the response tab of it's " &amp; _
"properties, edit the script and modify the parameter in question."
End If

Dim ADOConnection, strQuery
Dim strComputerName, strConfigurationPath, strServerName
strComputerName = TargetFQDNComputer

Initialize strComputerName, ADOConnection, strConfigurationPath, strServerName
If 0 &lt;&gt; Err Then
bAddItem=false
ScriptError "failed to initialize correctly." &amp; GetErrorString(Err)
Else
' Bind to this computer in AD
Dim oComputer
BindObject "LDAP://" &amp; strComputerName &amp; "/" &amp; strServerName, oComputer
If 0 &lt;&gt; Err Then
bAddItem=false
ScriptError "failed to bind to 'LDAP://" &amp; strComputerName &amp; "/" &amp; strServerName &amp; "'." &amp; GetErrorString(Err)
Else
' Check to see if multiple servers exist. If there is only a single server then
' don't run the test as it can't have any replicas.
strQuery = "&lt;LDAP://" &amp; strComputerName &amp; "/CN=Sites," &amp; strConfigurationPath &amp; "&gt;;(objectCategory=server);cn;subtree"
Dim iServers
iServers = ExecuteQueryAndCountRows(ADOConnection, strQuery)

Dim bLoneServer
If iServers &lt; 2 Then
bLoneServer = True
End If

If Not(bLoneServer) Then
' Search for outbound connections. (Which exist as inbound connections on other servers.)
strQuery = "&lt;LDAP://" &amp; strComputerName &amp; "/CN=Sites," &amp; strConfigurationPath &amp; "&gt;;" &amp; _
"(&amp;(objectCategory=nTDSConnection)" &amp; _
"(fromServer=CN=NTDS Settings," &amp; strServerName &amp; ")" &amp; _
"(|(!(Name=*DEL*))(!(Name=*CNF*)))" &amp; _
");cn;subtree"

iOutboundConnections = ExecuteQueryAndCountRows(ADOConnection, strQuery)

' Check to see if there are multiple sites. If there are then make sure
' that this site has an inbound connection from another one.
strQuery = "&lt;LDAP://" &amp; strComputerName &amp; "/CN=Sites," &amp; strConfigurationPath &amp; "&gt;;(objectCategory=siteObject);cn;onelevel"

Dim iSites
iSites = ExecuteQueryAndCountRows(ADOConnection, strQuery)

If iSites &gt; 1 Then
' Multiple sites exist. Ensure that there is at least one inbound connection
' from another site.

' Get this servers parent (which is this site.)
Dim oSite
Set oSite = GetObject(oComputer.Parent)

' Construct a query which will look for all inbound connections to this site,
' excluding all connections FROM this site.
strQuery = "&lt;LDAP://" &amp; strComputerName &amp; "/CN=" &amp; oSite.Name &amp; ",CN=Sites," &amp; strConfigurationPath &amp; "&gt;;(&amp;(objectCategory=connectionObject)"

Dim oServer
For Each oServer In oSite
strQuery = strQuery &amp; "(fromServer&lt;&gt;" &amp; oServer.distinguishedName &amp; ")"
Next

strQuery = strQuery &amp; ");cn;subtree"

Dim rsConnections
Set rsConnections = ADOConnection.Execute(strQuery)

bInterSiteConnectionExists = Not(rsConnections.EOF)
Else
bInterSiteConnectionExists = True
End If
End If

' If necessary, construct messages to notify the user of possible replication problems.
Dim strMessage
If Not(bLoneServer) AND (((iOutboundConnections = 0) And Not(bIsRODC)) Or Not (bInterSiteConnectionExists)) Then
strMessage = strMessage &amp; "The server, '" &amp; strComputerName &amp; "' " &amp; vbCrLf
Dim strJoin
strJoin = ""
If (iOutboundConnections = 0) And Not(bIsRODC) Then
strMessage = strMessage &amp; " has no outbound connections to any other server in this domain"
strJoin = " and " &amp; vbCrLf
End If
If Not(bInterSiteConnectionExists) Then
strMessage = strMessage &amp; strJoin &amp; " exists in a replication site island"
End If
strMessage = strMessage &amp; "."
CreateEvent EVENT_ID_REPLICATION_ISLAND, EVENT_TYPE_WARNING, strMessage
bLogSuccess = False
End If

' If appropriate, warn the user of excessive connections
strMessage = "The server, '" &amp; strComputerName &amp; "' " &amp; vbCrLf
If iOutboundConnections &gt; lWarningThreshold Then
strMessage = strMessage &amp; "has " &amp; CStr(iOutboundConnections) &amp; " outbound replication connections, which is more than the recommended number (" &amp; _
lWarningThreshold &amp; ")" &amp; vbCrLf
End If

If (iOutboundConnections &gt; lWarningThreshold) Then
If (iOutboundConnections &lt; lErrorThreshold) Then
CreateEvent EVENT_ID_TOO_MANY_CONNECTIONS, EVENT_TYPE_WARNING, strMessage
Else
CreateEvent EVENT_ID_TOO_MANY_CONNECTIONS, EVENT_TYPE_ERROR, strMessage
End If
bLogSuccess = False
End If

If bLogSuccess Then
If bLoneServer Then
strMessage = "The server, " &amp; strComputerName &amp; ", is the only server in this domain." &amp; vbCrLf
Else
strMessage = ""
End If

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

CreateEvent EVENT_ID_SUCCESS, EVENT_TYPE_INFORMATION, strMessage
End If
End If
End If
if bAddItem=true then
if nState=1 then
set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "FAILED"
oBag.AddValue "EventID", EVENT_ID_FAILED
oAPI.AddItem oBag
END IF
if nState=2 then
set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "WARNING"
oBag.AddValue "EventID", EVENT_ID_WARNING
oAPI.AddItem oBag
END IF
if nState=0 then
set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "SUCCESS"
oBag.AddValue "EventID", EVENT_ID_SUCCEEDED
oAPI.AddItem oBag
END IF
end if
oAPI.ReturnItems
Else
CreateEvent EVENT_ID_AGENTLESS, EVENT_TYPE_ERROR, "The AD Management Pack does not support the agentless management mode." &amp; vbCrLf &amp; _
"The script '" &amp; SCRIPT_NAME &amp; "' will not execute." &amp; vbCrLf &amp; _
"To prevent this alert being generated again, either change the monitoring " &amp; _
"mode of the computer '" &amp; TargetFQDNComputer &amp; "' to agent-managed " &amp; _
"or disable the rule that generated this alert."
End If
End Sub

'******************************************************************************
Sub CreateEvent(lngEventID, lngEventType, strMessage)
'
' Purpose: To create a MOM event
'
' Arguments: lngEventID, the event ID
' lngEventType, the event type (see values at top of file)
' strMessage, the message text for the event

oAPI.LogScriptEvent "AD Replication Partner Count", lngEventID, lngEventType, strMessage

if lngEventID=EVENT_ID_TOO_MANY_CONNECTIONS and lngEventType=EVENT_TYPE_ERROR then
nState=1
end if
if lngEventID=EVENT_ID_TOO_MANY_CONNECTIONS and lngEventType=EVENT_TYPE_WARNING then
if nState&lt;&gt;1 then
nState=2
end if
end if
if lngEventID=EVENT_ID_REPLICATION_ISLAND and nState &lt;&gt; 1 then
nState=2
end if
End Sub

'******************************************************************************
Sub BindObject(strBindPath, ByRef oOutput)
'
' Purpose: To bind to an object with error tolerance, throw an error if
' one occurs
'
' Arguments: strBindPath, the path of the object to bind to
' oOutput, the variable to hold the object once it
' has been bound to.
'
Dim oInternalObject

On Error Resume Next
Set oInternalObject = GetObject(strBindPath)

If Err.Number = 0 Then
Set oOutput = oInternalObject
Else
oOutput = nothing
Err.Raise Err.Number
End If

Set oInternalObject = nothing
End Sub

'******************************************************************************
Function Initialize(strComputerName, ByRef ADOConnection, ByRef strConfigurationPath, ByRef strServerName)
'
' Purpose: Initialize the base objects required by the rest of the script.
'
' Arguments: ADOConnection, object to store the new ADODB.Connection in
' strComputerName, stores the DNS name of the computer in
' strConfigurationPath, stores the configurationNamingContext in
' strServerName, stores the name of the server in
'
' Returns: True or False, True if initialization was successful
'
Initialize = False

' Setup an ADO connection
On Error Resume Next
Set ADOConnection = CreateObject("ADODB.Connection")
If Err.Number = 0 Then
ADOConnection.Provider = "ADSDsOObject"
ADOConnection.Open "ADs Provider"
If Err.Number = 0 Then
' Bind to the rootDSE to get the naming contexts
Dim oRootDSE
BindObject "LDAP://" &amp; strComputerName &amp; "/RootDSE", oRootDSE
If 0 &lt;&gt; Err Then
Set ADOConnection = nothing

Err.Raise Err.Number
End If

strConfigurationPath = oRootDSE.Get("ConfigurationNamingContext")
strServerName = oRootDSE.Get("ServerName")

If (Len(strConfigurationPath) = 0) Or (Len(strServerName) = 0) Then
Set ADOConnection = nothing

Err.Raise &amp;H80000000, "Invalid initialization detected:" &amp; vbCrLf &amp; _
"ConfigurationPath = " &amp; strConfigurationPath &amp; ", ServerName = " &amp; strServerName
Else
Initialize = True
End If
End If
Else
Err.Raise Err.Number
End If

End Function

'******************************************************************************
Function ExecuteQueryAndCountRows(ADOConnection, strQuery)
'
' Purpose: Executes the given query and counts the number of returned rows.
'
' Arguments: ADOConnection, the connection on which to execute the query
' strQuery, the query to execute
'
' Returns: The number of rows returned by the query. (0 if an error occurs)
'
Dim rsQuery
Set rsQuery = ADOConnection.Execute(strQuery)

ExecuteQueryAndCountRows = rsQuery.RecordCount

' Release the recordset
Set rsQuery = nothing
End Function

'******************************************************************************
Sub ScriptError(strError)
'
' Purpose: Records a script error.
'
' Parameters: strError, the description of the error to record
'
CreateEvent EVENT_ID_SCRIPT_ERROR, EVENT_TYPE_WARNING, "The script '" &amp; SCRIPT_NAME &amp; "' " &amp; strError
End Sub

'******************************************************************************
Function GetErrorString(oErr)
'
' Purpose: Attempts to find the description for an error if an error with
' no description is passed in.
'
' Parameters: oErr, the error object
'
' Return: String, the description for the error. (Includes the error code.)
'
Dim lErr, strErr
lErr = oErr
strErr = oErr.Description

On Error Resume Next
If 0 &gt;= Len(strErr) 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 = &amp;HFFFF0000
Const HiWord8007 = &amp;H80070000
Const LoWordMask = 65535 ' This is equivalent to 0x0000FFFF

If (lErr And ErrorMask) = HiWord8007 Then
' Attempt to use 'net helpmsg' to get a description for the error.
Dim oShell
Set oShell = CreateObject("WScript.Shell")
If Err = 0 Then
Dim oExec
Set oExec = oShell.Exec("net helpmsg " &amp; (lErr And LoWordMask))

Dim strMessage, i
Do
strMessage = oExec.stdout.ReadLine()
i = i + 1
Loop While (Len(strMessage) = 0) And (i &lt; 5)

strErr = strMessage
End If
End If
End If

GetErrorString = vbCrLf &amp; "The error returned was: '" &amp; strErr &amp; "' (0x" &amp; Hex(lErr) &amp; ")"
End Function

Call Main()

</Script></Contents>
<Unicode>1</Unicode>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>