AD Time Skew Datasource

AD_Time_Skew.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
TimeSourcestring$Config/TimeSource$Time Source
LogSuccessEventstring$Config/LogSuccessEvent$Log Success Event
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds

Source Code:

<DataSourceModuleType ID="AD_Time_Skew.DataSource" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element name="TargetComputerName" type="xsd:string"/>
<xsd:element name="TimeSource" 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="TimeSource" Selector="$Config/TimeSource$" ParameterType="string"/>
<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_Time_Skew.vbs$ $Config/TargetComputerName$ $Config/LogSuccessEvent$ $Config/TimeSource$</CommandLine>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>AD_Time_Skew.vbs</Name>
<Contents><Script>
'*************************************************************************
' Script Name - AD Time Skew Detection
'
' Purpose - Determines if the time source for the domain varies
' from the MOM server
'
' 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
'*************************************************************************

Option Explicit

Const EVENT_ID_SUCCESS = 99
Const EVENT_ID_WARNING = 100
Const EVENT_ID_ERROR = 101
Const EVENT_ID_DEBUG = 103

Const EVENT_TYPE_SUCCESS = 0
Const EVENT_TYPE_WARNING = 2
Const EVENT_TYPE_ERROR = 1

' TypedPropertyBag
const PerformanceDataType = 2
const StateDataType = 3

Dim tmScriptStart
Dim oAPI

Sub Main()
'Variables for time on local machine
Dim strLocalServer
Dim LocalRootDSE
Dim strLocalTime
Dim tmLocal

'Variables for time on gTimeServer
Dim strTimeServer
Dim TimeRootDSE
Dim strTimeTime
Dim tmTime

'Vars for getting the PDC FSMO
Dim ADOconnObj
Dim bstrADOQueryString
Dim RootDom
Dim RSObj
Dim FSMOobj
Dim CompNTDS
Dim LocalPDC
Dim RootPDC
Dim strLocalPDC

Dim iSecondsDiff

Dim bSuccess

tmScriptStart = Now

If WScript.Arguments.Count &lt; 2 Or WScript.Arguments.Count &gt; 3 Then
Wscript.Echo "Invalid number of arguments!"
Wscript.Quit -1
End If

strLocalServer = Wscript.Arguments(0)
strTimeServer = ""
bSuccess = CBool(Wscript.Arguments(1))


If WScript.Arguments.Count = 3 Then
strTimeServer = Wscript.Arguments(2)
End If

Set oAPI = CreateObject("Mom.ScriptAPI")

On Error Resume Next

' If we are in "Autodetect" mode
If strTimeServer = "" Then
Set ADOconnObj = CreateObject("ADODB.Connection")
If Err Then
CreateEvent EVENT_ID_ERROR, EVENT_TYPE_ERROR, "Unable to create ADODB Connection. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End IF

ADOconnObj.Provider = "ADSDSOObject"
ADOconnObj.Open "ADs Provider"

Set RootDom = GetObject("LDAP://RootDSE")
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to contact Root DSE. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

' Locate the local PDC
bstrADOQueryString = "&lt;LDAP://" &amp; RootDom.Get("DnsHostName") &amp; "&gt;;(&amp;(objectClass=domainDNS)(fSMORoleOwner=*));adspath;subtree"
Set RSObj = ADOconnObj.Execute(bstrADOQueryString)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to execute ADO query. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

Set FSMOobj = GetObject(RSObj.Fields(0).Value)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to locate local domain FSMO. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

Set CompNTDS = GetObject("LDAP://" &amp; FSMOobj.fSMORoleOwner)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to query local domain FSMO role owner. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

Set LocalPDC = GetObject(CompNTDS.Parent)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to locate local domain PDC. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

strLocalPDC = LocalPDC.dnsHostName

' If we are the PDC of the local domain
If strLocalServer = strLocalPDC Then

'Get a DC in the root domain
Dim bstrRootDomainNamingContext
Dim strServer
bstrRootDomainNamingContext = RootDom.Get("rootDomainNamingContext")
Set FSMOobj = GetObject("LDAP://" &amp; bstrRootDomainNamingContext)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to locate root domain naming context. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

strServer = FSMOobj.GetOption(0)

'Get the PDC of the root domain
Set CompNTDS = GetObject("LDAP://" &amp; strServer &amp; "/" &amp; FSMOobj.fSMORoleOwner)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to query root domain FSMO role owner. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

Set RootPDC = GetObject(CompNTDS.Parent)
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to locate root domain PDC. The error was: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

strTimeServer = RootPDC.dnsHostName ' Use the forest root PDC
Else
strTimeServer = LocalPDC.dnsHostName ' Use the local PDC
End If
End If

If strTimeServer = "" Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to determine name of time source"
Exit Sub
End If

Set LocalRootDSE = GetObject("LDAP://" &amp; strLocalServer &amp; "/RootDSE")
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to contact " &amp; strLocalServer &amp; " to determine time. Error: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

Set TimeRootDSE = GetObject("LDAP://" &amp; strTimeServer &amp; "/RootDSE")
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to contact " &amp; strTimeServer &amp; " to determine time. Error: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

strLocalTime = LocalRootDSE.Get("currentTime")
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to retrieve current time from " &amp; strLocalServer &amp; ". Error: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

strTimeTime = TimeRootDSE.Get("currentTime")
If Err Then
CreateEvent EVENT_ID_WARNING, EVENT_TYPE_WARNING, "Unable to retrieve current time from " &amp; strTimeServer &amp; ". Error: " &amp; Err.Description &amp; " (" &amp; Hex(Err.number) &amp; ")"
Exit Sub
End If

tmTime = CDate(ConvertTimeStamp(strTimeTime))
tmLocal = CDate(ConvertTimeStamp(strLocalTime))

iSecondsDiff = Abs(DateDiff("s",tmTime,tmLocal))

CreatePerformanceData iSecondsDiff

If bSuccess Then
CreateEvent EVENT_ID_SUCCESS, EVENT_TYPE_SUCCESS, BuildEventMessage(strLocalServer, strTimeServer, iSecondsDiff, tmLocal, tmTime)
End If

oAPI.ReturnItems
End Sub

'******************************************************************************
Function ConvertTimeStamp(strUTCTime)
'
' Purpose: Convert a timestamp into a human-readable format
'
' Paramters: strUTCTime, the timestamp to be converted
'
dim sYear
dim sMonth
dim sDay
dim sHour
dim sMinute
dim sSecond

sYear = Mid(strUTCTime, 1, 4)
sMonth = Mid(strUTCTime, 5, 2)
sDay = Mid(strUTCTime, 7, 2)
sHour = Mid(strUTCTime, 9, 2)
sMinute = Mid(strUTCTime, 11, 2)
sSecond = Mid(strUTCTime, 13, 2)

ConvertTimeStamp = sMonth &amp; "/" &amp; sDay &amp; "/" &amp; sYear &amp; " " &amp; sHour &amp; ":" &amp; sMinute &amp; ":" &amp; sSecond
End Function

'******************************************************************************
Sub CreateEvent(lEventID, lEventType, strMessage)
'
' Purpose: To create a MOM event
'
' Arguments: lEventID, the event ID
' lEventType, the event type (see values at top of file)
' strMessage, the message text for the event
'
oAPI.LogScriptEvent "AD Time Skew", lEventID, lEventType, strMessage
End Sub

'******************************************************************************
Sub CreatePerformanceData(lngValue)
'
' Purpose: Creates performance data for MOM
'
' Parameters: lngValue, the value of the counter
'
On Error Resume Next

Dim oBag
Set oBag= oAPI.CreateTypedPropertyBag(PerformanceDataType)
Call oBag.AddValue("StatusObject", "ActiveDirectoryMP")
Call oBag.AddValue("StatusCounter", "Time Skew")
Call oBag.AddValue("StatusInstance", "")
Call oBag.AddValue("StatusValue", lngValue)
Call oAPI.addItem(oBag)

End Sub

'******************************************************************************
Function BuildEventMessage(sLServ, sTServ, iDiff, timeL, timeT)
'
' Purpose: Produce a preformatted event message used to log a success
' event
'
' Parameters: sLServ, the name of the local machine
' sRServ, the name of the time source being compared to
' iDiff, the number of seconds that the machines differ
' timeL, the current time on the local machine
' timeT, the current time on the time source

BuildEventMessage = "Time check test has occured between " &amp; sLServ &amp; " and " &amp; sTServ &amp; vbCrLf &amp; _
"The current time skew is " &amp; iDiff &amp; " seconds" &amp; vbCrLf &amp; vbCrLf &amp; _
"Time on local dc (" &amp; sLServ &amp; ") is " &amp; timeL &amp; vbCrLf &amp; _
"Time on gtimeserv (" &amp; sTServ &amp; ") is " &amp; timeT &amp; vbCrLf &amp; "Script has taken " &amp; Int((now - tmScriptStart)*24*60*60) &amp; " seconds to run"
End Function

Main()

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