The syntax to run the script is:
c:\cscript fl.vbs <authoritative_dc_name>
'File Name: fl.vbs
Option Explicit
'Global constants
Const LINK_PINGCOUNT = 1
const ERROR_SUCCESS = 0
'Main
GetDCList
'End Main
'=============================================================
Function GetDCList
Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery
Dim adoRecordset, objDC, objSite
Dim strAuthDC, strDC, strSite
' We need a DC that can give us authoritative information
If WScript.Arguments.Count = 1 Then
strAuthDC = WScript.Arguments.Item(0)
Else
Wscript.Echo "Usage: fl.vbs <DCName>"
Wscript.Quit
End If
Wscript.Echo "Using " & strAuthDC & " as the authoritative DC...." & vbCrLf
' Determine configuration context from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
' Use ADO to search Active Directory for ObjectClass nTDSDSA.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
strQuery = "<LDAP://" & strAuthDC & "/" & strConfig _
& ">;(ObjectClass=nTDSDSA);AdsPath;subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute
Do Until adoRecordset.EOF
Set objDC = GetObject( _
GetObject(adoRecordset.Fields("AdsPath").Value).Parent)
Set objSite = GetObject(GetObject(objDC.Parent).Parent)
strDC = objDC.DNSHostName
strSite = objSite.cn
If VerifyHostPing(strDC) Then
Call ProcessDCList(strDC,strSite)
End If
adoRecordset.MoveNext
Loop
adoRecordset.Close
' Clean up.
adoConnection.Close
Set objRootDSE = Nothing
Set adoCommand = Nothing
Set adoConnection = Nothing
Set adoRecordset = Nothing
Set objDC = Nothing
Set objSite = Nothing
Wscript.Echo "Done"
End Function
'==================================================================
Function VerifyHostPing(ByRef strComputer)
Dim objWMI, strQuery, i, objPings, objStatus
Set objWMI = GetObject("winmgmts:{impersonationLevel=impersonate}!\root\cimv2")
VerifyHostPing = False
strQuery = "Select * From Win32_PingStatus where Address = '" & strComputer & "' AND BufferSize = 32 and Timeout = 300"
For i = 1 to LINK_PINGCOUNT
Set objPings = objWMI.ExecQuery(strQuery)
For Each objStatus in objPings
If IsNull(objStatus.StatusCode) OR objStatus.StatusCode <> ERROR_SUCCESS Then
wscript.echo "Warning: " & strComputer & " not contactable." & vbCrLf
VerifyHostPing = False
Else
'wscript.echo "Successfully pinged " & strComputer
VerifyHostPing = True
End If
Next
Next
Set objPings = Nothing
Set objStatus = Nothing
Set objWMI = Nothing
End Function
'==================================================================
Sub ProcessDCList(varDC,varSite)
Dim Domain, strDomain, objRootDSE, strDFL, Forest, strFFL
Const ADS_PROPERTY_NOT_FOUND = &h8000500D
Wscript.Echo "Checking DC: " & varDC & " in site: " & varSite
Set objRootDSE = GetObject("LDAP://" & varDC & "/RootDSE")
strDomain = objRootDSE.Get("DefaultNamingContext")
On Error Resume Next
set Domain = GetObject("LDAP://" & varDC & "/" & strDomain)
strDFL = Domain.Get("msDS-Behavior-Version")
If Err.Number <> ADS_PROPERTY_NOT_FOUND Then
WScript.Echo "Domain Functional Level is " & strDFL
Else
WScript.Echo "Domain Functional Level is 0"
Err.Clear
End If
On Error Resume Next
set Forest = GetObject("LDAP://" & varDC & "/cn=partitions," & _
objRootDSE.Get("configurationNamingContext"))
strFFL = Forest.Get("msDS-Behavior-Version")
If Err.Number <> ADS_PROPERTY_NOT_FOUND Then
WScript.Echo "Forest Functional Level is " & strFFL
Else
WScript.Echo "Forest Functional Level is 0"
Err.Clear
End If
Wscript.Echo vbCrLf
End Sub
'==================================================================
Alexei
8th April 2009