AD Client Serverless Bind Script Datasource

AD_Client_Serverless_Bind.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$Interval Seconds
LogSuccessEventstring$Config/LogSuccessEvent$Log Success Event
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds

Source Code:

<DataSourceModuleType ID="AD_Client_Serverless_Bind.DataSource" Accessibility="Internal">
<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" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="LogSuccessEvent" ParameterType="string" Selector="$Config/LogSuccessEvent$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterPropertyBagSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%windir%\system32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>//nologo $file/AD_Client_Serverless_Bind.vbs$ $Config/TargetComputerName$ $Config/LogSuccessEvent$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>AD_Client_Serverless_Bind.vbs</Name>
<Contents><Script>
'*************************************************************************
' Script Name - AD Client Serverless Bind
'
' Purpose - Does a serverless bind and determines whether the returned
' DC is in the same site as the client
'
' Assumptions - Script is run by a timed event
'
' Parameters - LogSuccessEvent - Logs an event when the script completes.
'
' (c) Copyright 2002, 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

' Standard Event IDs
Const EVENT_ID_SUCCESS = 5000
Const EVENT_ID_SCRIPT_FAILURE = 5001
'Const EVENT_ID_EVENT_RULE_ONLY = 5002
Const EVENT_ID_INVALID_PARAMETER = 5003
Const EVENT_ID_AGENTLESS = 98

' Base Event ID
Const EVENT_ID_DC_OUT_OF_SITE = 1105
Const EVENT_ID_DC_NOT_OUT_OF_SITE = 895

' Other Constants
Const SCRIPT_NAME = "AD Client Serverless Bind"

' TypedPropertyBag
const StateDataType = 3

' Other Variables
Dim oParams, TargetFQDNComputer, bLogSuccessEvent, IsTargetAgentless, oAPI, oBag
Set oParams = WScript.Arguments

if oParams.Count &lt; 2 then
Wscript.Quit -1
End if

TargetFQDNComputer = oParams(0)
bLogSuccessEvent = CBool(oParams(1))'LogSuccessEvent
IsTargetAgentless = False
Set oAPI = CreateObject("Mom.ScriptAPI")
Err.Clear

Sub Main()
On Error Resume Next
Dim dtStart
dtStart = Now

If Not(IsTargetAgentless) Then

' Obtain the RootDSE of any Domain Controller that this client computer can connect to.
Dim oRootDSE
Set oRootDSE = GetObject("LDAP://RootDSE")

If 0 &lt;&gt; Err Then
ScriptError "attempting to bind to the RootDSE of any DC in the domain."
Else
' Now query the root DSE to get the site of the DC
Dim strSite, strServerName, strDNSHostName
strServerName = oRootDSE.Get("ServerName")
strDNSHostName = oRootDSE.Get("DNSHostName")
If 0 &lt;&gt; Err Then
ScriptError "attempting to obtain the 'ServerName' and the 'DNSHostName' attributes of the DC '" &amp; strDNSHostName &amp; "'."
End If
End If

' Create OOMADS Object for querying the directory. Fail script execution of creation fails.
Dim oOOMADS
Set oOOMADS = CreateObject("McActiveDir.ActiveDirectory")
If (0 &lt;&gt; Err.Number) Or (Not(IsObject(oOOMADS))) Then
Dim errorString
errorString = "The script '" &amp; SCRIPT_NAME &amp; "' failed to create object " &amp; _
"'McActiveDir.ActiveDirectory'. This is an unexpected error." &amp; vbCrLf &amp; vbCrLf &amp; _
GetErrorString(Err) &amp; vbCrLf &amp; vbCrLf &amp; _
"The Active Directory Management Pack Objects (OOMADs) components are not installed on the Domain Controller. These components are required for the monitoring scripts to run successfully. See Alert Knowledge for additional details."

CreateEvent EVENT_ID_SCRIPT_FAILURE, EVENT_TYPE_WARNING, errorString
Else
' Check if the DC responding to the RootDSE query is supposed to cover the site to which this Client monitoring machine belongs.
Dim bClosestSite
bClosestSite = oOOMADS.IsDCInClosestSite(strDNSHostName)
If 0 &lt;&gt; Err.number Then

Dim strClosestSiteError
strClosestSiteError = "attempting to determine if the DC '" &amp; strDNSHostName &amp; "' is configured to cover the AD local site of the machine '" &amp; TargetFQDNComputer &amp; "'." &amp; vbCrLf &amp; vbCrLf

If Err.number = &amp;H80004005 Then
' If we get error E_FAIL, OOMADS has determined that the ClientSiteName property of the computer object for TargetFQDNComputer is not associated to any site. Let the user know so he can fix this.
strClosestSiteError = strClosestSiteError &amp; "The computer object for the client machine is not associated to any Active Directory Site." &amp; vbCrLf &amp; vbCrLf
strClosestSiteError = strClosestSiteError &amp; "To fix this issue, associate the machine's computer object to an Active Directory Site."
End If

ScriptError strClosestSiteError

Else
If Not bClosestSite Then
Dim strDcSite, strClientSite

strClientSite = GetLocalSiteName()
strDcSite = GetDCSiteName(strDNSHostName)

Dim strMessage
strMessage = "A serverless bind returned a domain controller that was not " &amp; _
"in the same site as the client machine." &amp; vbCrLf &amp; vbCrLf
strMessage = strMessage &amp; "Client Machine: " &amp; TargetFQDNComputer &amp; vbCrLf
strMessage = strMessage &amp; "Client Site: " &amp; strClientSite &amp; vbCrLf
strMessage = strMessage &amp; "Domain Controller Responding to Serverless bind: " &amp; strDNSHostName &amp; vbCrLf
strMessage = strMessage &amp; "Domain Controller Site: " &amp; strDcSite
CreateEvent EVENT_ID_DC_OUT_OF_SITE, EVENT_TYPE_WARNING, strMessage

Set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "BAD"
oBag.AddValue "EventID", "" &amp; EVENT_ID_DC_OUT_OF_SITE
oBag.AddValue "ErrorString", strMessage
oAPI.AddItem oBag
Else
Set oBag = oAPI.CreateTypedPropertyBag(StateDataType)
oBag.AddValue "State", "GOOD"
oBag.AddValue "EventID", "" &amp; EVENT_ID_DC_NOT_OUT_OF_SITE
oAPI.AddItem oBag
If bLogSuccessEvent Then
CreateEvent EVENT_ID_SUCCESS, EVENT_TYPE_INFORMATION, "The script '" &amp; SCRIPT_NAME &amp; _
"' completed successfully in " &amp; DateDiff("s", dtStart, Now) &amp; _
" second(s)."
End If
End If
End If
End If

Call 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

'******************************************************************************
Function GetLocalSiteName()
'
' Purpose: To retrieve the site name for this computer.
'
' Returns: String, the site name (or an empty string if it cannot be determined)
'
Dim oADSysInfo
Set oADSysInfo = CreateObject("ADSystemInfo")

If Err &lt;&gt; 0 Then
ScriptError "creating the 'ADSystemInfo' object."
GetLocalSiteName = "Unknown"
Else
GetLocalSiteName = oADSysInfo.SiteName
End If
End Function

'******************************************************************************
Function GetDCSiteName(strDcName)
'
' Purpose: To retrieve the site name for a given DC.
'
' Returns: String, the site name (or an empty string if it cannot be determined)
'
Dim oADSysInfo
Set oADSysInfo = CreateObject("ADSystemInfo")

If Err &lt;&gt; 0 Then
ScriptError "creating the 'ADSystemInfo' object."
GetDCSiteName = "Unknown"
Else
GetDCSiteName = oADSysInfo.GetDCSiteName(strDcName)
End If
End Function

'******************************************************************************
Sub CreateEvent(lEventID, lEventType, strMessage)
'
' Purpose: To generate a MOM event
'
' Arguments: lEventID, the event code
' lEventType, the severity of the event
' strMessage, the message to include in the event
'
On Error Resume Next
oAPI.LogScriptEvent "AD Client Serverless Bind" ,lEventID, lEventType, strMessage
End Sub

'******************************************************************************
Sub ScriptError(strContext)
'
' Purpose: To generate an alert for the current error and then throw the
' exception so it can be caught at a higher level.
'
' Arguments: strContext - the current context, this is added to the message
' that is alerted to the user
'
' Returns: nothing
'
Dim strError
strError = "The script '" &amp; SCRIPT_NAME &amp; "' encountered an error while " &amp; strContext &amp; _
GetErrorString(Err)

CreateEvent EVENT_ID_SCRIPT_FAILURE, EVENT_TYPE_WARNING, 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>