Option Explicit '------------------------------------------------------------------------- ' checkagmode.2.1.vbs ' ' Beschreibung ' Listet die betriebsart aller AdminGroups auf ' ' Option /Server:servername Angabe eines DC, der gefragt wird ' Laufzeitfehler werde nicht abgefangen und beenden das Skript. ' ' Das Skript wird mit den Berechtigungen des angemeldeten Benutzers ' ausgeführt. Die entsprechenden Berechtigungen sind sicher zu stellen ' ' (c)2005 Frank Carius ' ' Version 1.0 (25 Juli 2005) ' Version 2.0 (10. Aug 2005) FC ' - Page Size und weitere Felder ergänzt ' - XSL wird mit angelegt ' - umfangreiches Reporting zu SRS und DSA ' Version 2.1 (10. Aug 2005) FC ' - Umstellung auf DebugWriter und neue XML-Classen ' - Erweiterung auf ConfigCA Suche, Option Targetserver '------------------------------------------------------------------------- Dim objRootDSE ' Dim strConfigurationNC ' Dim oCommand ' Dim oConnection ' Dim oRecordSet ' Dim strAGContainer ' Dim strQuery dim strExchangeOrg, strtargetserver, strOutFilePrefix Dim inttotal, intmodemixed, intmodenative, intmodeex55 dim xmlWriter dim exitcode strOutFilePrefix = "CheckAGMode-" & Date() & "-" & Replace(Time(),":","-") ' Pfad und Dateiname der Debug-Datei dim objDebug set objdebug = new DebugWriter objDebug.level=3 ' errorlogging 0=only output, 1=Error 2=Warning 3=information 5++ =debug objDebug.target = "file, console" ' ie eventlog objDebug.outFile = strOutFilePrefix & ".log" objDebug.start call ForceCScript ' must be rund with CSCRIPT call abbruch ("Script fortsetzen ?" ,5) ' Last question to stop objDebug.writeln "Skript "& WScript.ScriptName &" gestartet", 0 exitcode = 0 call WriteXSL("checkagmode.xsl") objDebug.writeln "XSL-Datei geschrieben", 4 set xmlWriter = new XmlTextWriter xmlWriter.filename = strOutFilePrefix & ".xml" xmlWriter.Indentation = 4 call xmlWriter.WriteStylesheet("checkagmode.xsl") call xmlWriter.WriteStartElement("checkagmode") call xmlWriter.WriteElementString("starttime", now()) strtargetserver = wscript.arguments.named("Server") objDebug.writeln "Targetserver: "& strtargetserver, 0 call xmlWriter.WriteElementString("targetserver", strtargetserver) if strtargetserver <> "" then strtargetserver = strtargetserver & "/" objDebug.writeln "Searching für RootDSE", 4 Set objRootDSE = GetObject("LDAP://" & strtargetserver & "RootDSE") strConfigurationNC = objRootDSE.Get("configurationNamingContext") objDebug.writeln "ConfigNC=" & strConfigurationNC, 4 objDebug.writeln "Searching für Exchange Org using ADODB", 0 Set oConnection = CreateObject("ADODB.Connection") Set oCommand = CreateObject("ADODB.Command") Set oRecordSet = CreateObject("ADODB.RecordSet") oConnection.Provider = "ADsDSOObject" oConnection.Open "ADs Provider" strQuery = ";(objectclass=msExchOrganizationContainer);"& "name,distinguishedName" objDebug.writeln "LDAP-String"&strQuery,4 oCommand.ActiveConnection = oConnection oCommand.CommandText = strQuery Set oRecordSet = oCommand.Execute objDebug.writeln "DONE: Records Found:" & oRecordSet.recordcount,4 if oRecordSet.EOF then objDebug.writeln "Unable to read Exchange Organization, Check AD-permissions.", 1 CreateAlert "OrgRead", "Unable to read Exchange Organization, Check AD-permissions.",EVENT_SOURCE,50 call xmlWriter.WriteElementString("orgname", "NOTFOUND") exitcode = 1 else objDebug.writeln "FOUND:Orgname=" & oRecordSet.Fields("name"), 0 objDebug.writeln "OrgDN=" & oRecordSet.Fields("distinguishedName"), 4 strExchangeOrg = oRecordSet.Fields("name") call xmlWriter.WriteElementString("orgname", strExchangeOrg) strAGContainer = "CN=Administrative Groups,CN=" & strExchangeOrg & ",CN=Microsoft Exchange,CN=Services," & strConfigurationNC Set oConnection = CreateObject("ADODB.Connection") Set oCommand = CreateObject("ADODB.Command") Set oRecordSet = CreateObject("ADODB.RecordSet") oConnection.Provider = "ADsDSOObject" ' Open the Connection oConnection.Open "ADs Provider" ' Build the query to find all Servers strQuery = ";(objectClass=msExchAdminGroup);name,AdminDisplayName,msExchAdminGroupMode,distinguishedname;subtree" objDebug.writeln "LDAP-String:"&strQuery,4 oCommand.ActiveConnection = oConnection oCommand.Properties("Page Size") = 100 oCommand.CommandText = strQuery Set oRecordSet = oCommand.Execute if oRecordSet.recordcount = 0 then objDebug.writeln "AGSearch:Unable to read Exchange Admin Groups. Check AD-permissions.", 1 CreateAlert "AGSearch:Unable to read Exchange Admin Groups. Check AD-permissions.",EVENT_SOURCE,50 exitcode = 2 else objDebug.writeln "AGSearch: #AG=" & oRecordSet.recordcount, 0 inttotal = 0 : intmodemixed = 0 : intmodenative = 0 : intmodeex55 = 0 While (Not oRecordSet.EOF) inttotal = inttotal +1 objDebug.writeln "-------------------------------------------------------",0 objDebug.writeln "Name : "& oRecordSet.Fields("name"),0 objDebug.writeln "AdminDisplayName : "& oRecordSet.Fields("AdminDisplayName"),0 objDebug.writeln "msExchAdminGroupMode: "& oRecordSet.Fields("msExchAdminGroupMode"),0 call xmlWriter.WriteStartElement("ag") ' call xmlwriter.WriteAttributeString("name",oRecordSet.Fields("name")) call xmlWriter.WriteElementString("name",oRecordSet.Fields("name")) call xmlWriter.WriteElementString("admindisplayname" ,oRecordSet.Fields("AdminDisplayName")) call xmlWriter.WriteElementString("mode",oRecordSet.Fields("msExchAdminGroupMode")) select case oRecordSet.Fields("msExchAdminGroupMode") case "0" intmodenative = intmodenative +1 case "1" intmodeex55 = intmodeex55 +1 case "2" intmodemixed = intmodemixed +1 end select ' 0=Native E2K AG, 1= native EX55, 2= mixed AG call dumpSRS(oRecordSet.Fields("distinguishedname")) call dumpDSA(oRecordSet.Fields("distinguishedname")) call dumpConfigCA(oRecordSet.Fields("Name")) call xmlWriter.WriteEndElement() oRecordSet.MoveNext Wend objDebug.writeln "-------------AG Total :"&inttotal ,0 call xmlWriter.WriteElementString("total", inttotal) objDebug.writeln "-------------AG Native:"&intmodenative ,0 call xmlWriter.WriteElementString("agnative", intmodenative) objDebug.writeln "-------------AG Mixed :"&intmodemixed ,0 call xmlWriter.WriteElementString("agmixed", intmodemixed) objDebug.writeln "-------------AG EX55 :"&intmodeex55 ,0 call xmlWriter.WriteElementString("agex55", intmodeex55) call xmlWriter.WriteElementString("endtime", now()) call xmlWriter.WriteEndElement() end if end if call xmlwriter.close oRecordSet.Close 'Clean up oConnection.Close Set oRecordSet = Nothing Set oCommand = Nothing Set oConnection = Nothing objDebug.writeln "Skript beendet mit EXITCODE:"&exitcode, 0 WScript.quit(exitcode) sub dumpSRS(strAGDN) dim oConnection, oCommand, oRecordSet, intsrscount intsrscount = 0 objDebug.writeln "Searching für SRS in AG using ADODB", 4 Set oConnection = CreateObject("ADODB.Connection") Set oCommand = CreateObject("ADODB.Command") Set oRecordSet = CreateObject("ADODB.RecordSet") oConnection.Provider = "ADsDSOObject" ' Open the Connection oConnection.Open "ADs Provider" ' Build the query to find all Servers strQuery = ";(objectClass=msExchSiteReplicationService);name,mailNickname,distinguishedName;subtree" objDebug.writeln "LDAP-String:"&strQuery,4 oCommand.ActiveConnection = oConnection oCommand.Properties("Page Size") = 100 oCommand.CommandText = strQuery Set oRecordSet = oCommand.Execute While (Not oRecordSet.EOF) intsrscount = intsrscount + 1 objDebug.writeln "Name : "& oRecordSet.Fields("name"),3 objDebug.writeln "mailNickName: "& oRecordSet.Fields("mailNickName"),3 call xmlWriter.WriteStartElement("srs") call xmlWriter.WriteElementString("name",oRecordSet.Fields("name")) call xmlWriter.WriteElementString("distinguishedname" ,oRecordSet.Fields("distinguishedName")) call xmlWriter.WriteElementString("mailnickname",oRecordSet.Fields("mailNickname")) call xmlWriter.WriteEndElement() oRecordSet.MoveNext Wend objDebug.writeln "Done. Found " & intsrscount &" SRS-Items", 3 oRecordSet.Close 'Clean up oConnection.Close Set oRecordSet = Nothing Set oCommand = Nothing Set oConnection = Nothing end sub sub dumpConfigCA (strAG) dim oConnection, oCommand, oRecordSet, intConfigCAcount intConfigCAcount = 0 objDebug.writeln "Searching für ConfigCA für AG using ADODB", 4 Set oConnection = CreateObject("ADODB.Connection") Set oCommand = CreateObject("ADODB.Command") Set oRecordSet = CreateObject("ADODB.RecordSet") oConnection.Provider = "ADsDSOObject" ' Open the Connection oConnection.Open "ADs Provider" strQuery = ";"_ & "(&(objectClass=msExchConnectionAgreement)(msExchIsConfigCA=TRUE)(msExchExchangeSite=ou=" & strAG & ",o=" & strExchangeOrg & "));"_ & "name,distinguishedName,msExchExchangeSite;subtree" objDebug.writeln "LDAP-String:"&strQuery,4 oCommand.ActiveConnection = oConnection oCommand.Properties("Page Size") = 100 oCommand.CommandText = strQuery Set oRecordSet = oCommand.Execute While (Not oRecordSet.EOF) intConfigCAcount = intConfigCAcount + 1 objDebug.writeln "Name : "& oRecordSet.Fields("name"),3 call xmlWriter.WriteStartElement("configca") call xmlWriter.WriteElementString("name",oRecordSet.Fields("name")) call xmlWriter.WriteEndElement() oRecordSet.MoveNext Wend objDebug.writeln "Done. Found " & intConfigCAcount &" ConfigCA-Items", 3 oRecordSet.Close 'Clean up oConnection.Close Set oRecordSet = Nothing Set oCommand = Nothing Set oConnection = Nothing end sub sub dumpDSA(strAGDN) dim oConnection, oCommand, oRecordSet, intDSAcount intDSAcount = 0 objDebug.writeln "Searching für DSA in AG using ADODB", 4 Set oConnection = CreateObject("ADODB.Connection") Set oCommand = CreateObject("ADODB.Command") Set oRecordSet = CreateObject("ADODB.RecordSet") oConnection.Provider = "ADsDSOObject" ' Open the Connection oConnection.Open "ADs Provider" ' Build the query to find all Servers strQuery = ";(objectClass=msExchReplicationConnector);name,LocalBridgeHead,remoteBridgeHead,distinguishedName;subtree" objDebug.writeln "LDAP-String:"&strQuery,4 oCommand.ActiveConnection = oConnection oCommand.Properties("Page Size") = 100 oCommand.CommandText = strQuery Set oRecordSet = oCommand.Execute While (Not oRecordSet.EOF) intDSAcount = intDSAcount + 1 objDebug.writeln "Name : "& oRecordSet.Fields("name"),3 call xmlWriter.WriteStartElement("dsa") call xmlWriter.WriteElementString("name",oRecordSet.Fields("name")) call xmlWriter.WriteElementString("distinguishedname" ,oRecordSet.Fields("distinguishedName")) call xmlWriter.WriteElementString("localbridgehead",oRecordSet.Fields("LocalBridgeHead")) call xmlWriter.WriteElementString("remotebridgehead",oRecordSet.Fields("remoteBridgeHead")) call xmlWriter.WriteEndElement() oRecordSet.MoveNext Wend objDebug.writeln "Done. Found " & intDSAcount &" DSA -Items", 3 oRecordSet.Close 'Clean up oConnection.Close Set oRecordSet = Nothing Set oCommand = Nothing Set oConnection = Nothing end sub sub WriteXSL(xslfilename) Dim file, fs Set fs = CreateObject("Scripting.FileSystemObject") Set file = fs.OpenTextFile(xslfilename, 2, True) ' für Writing file.writeline("") file.writeline("") file.writeline("") file.writeline("") file.writeline("Exchange Adming Group Mode") file.writeline("") file.writeline("

Exchange Admingroups der Organisation

") file.writeline("

Zusammenfassung

") file.writeline("") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline("
Starttime
EndTime
TargetServerrandom
Anzahl AG-Mode TOTAL
# AG-Mode Native
# AG-Mode Mixed
# AG-Mode Ex55
# SRS-Services
# ConfigCA
# DSA-Connectors
") file.writeline("

Details

") file.writeline("") file.writeline("") file.writeline("") file.writeline("") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline(" ") file.writeline("") file.writeline("
AdmingroupDisplaynameGroupmodeSRS-ServersConfigCADSA-Connectors
not definedNative ()Invalid Configuration: SRS exists
") file.writeline("
No SRSInvalid Configuration: ConfigCA exists
") file.writeline("
No ConfigCAInvalid Configuration: DSA exists
") file.writeline(" - ) <->
") file.writeline("
") file.writeline("
no DSAEx55 ()Invalid Configuration: SRS exists
") file.writeline("
No SRSInvalid Configuration: ConfigCA exists
") file.writeline("
No ConfigCADSA exists
") file.writeline(" - ) <->
") file.writeline("
") file.writeline("
DSA Missing !Mixed ()SRS Found:

SRS Missing !!ConfigCA exists
") file.writeline("
Missing ConfigCADSA Found") file.writeline(" - ) <->
") file.writeline("
") file.writeline("
DSA Missing !Unbekannt:()Invalid ConfigurationInvalid Configuration
") file.writeline("Legende: Weiss = EX55, Geld = mixed, Gruen = Native 200x, Rot=Unbekannt") file.writeline("") file.writeline("") file.writeline("
") file.writeline("
") file.close end sub ' ================================================== Auxilary procedures and classes ========================== class XMLTextWriter '~ usage in VBScript. Please define StyleSheet and filename first and than start writing the data '~ set xmlWriter = new XmlTextWriter '~ xmlWriter.filename = "filename.xml" '~ xmlWriter.Indentation = 4 '~ call xmlWriter.WriteStylesheet("stylesheet.xsl") '~ call xmlWriter.WriteStartElement("root") '~ call xmlWriter.WriteElementString("starttime", now()) '~ call xmlWriter.WriteEndElement '~ call xmlWriter.close dim intIndentation dim level, tagopen dim Stack(100) ' i have problems using redim, so i use a fixed number für the depth dim fs, xmlfile private Sub Class_Initialize intIndentation = 4 level = 0 tagopen = false End Sub public Property let filename(wert) Set fs = CreateObject("Scripting.FileSystemObject") Set xmlfile = fs.OpenTextFile(wert, 2, True) ' 2 = ForWriting xmlfile.write "" & vbcrlf End Property public Property let Indentation(wert) intIndentation = wert End Property sub Writestylesheet (item) '* xmlfile.write "" & vbcrlf end sub sub WriteStartElement(item) xmlfile.write vbcrlf & space(intIndentation*level) & "<" & quote(trim(item)) ' & ">" ' Ende offen tagopen = true stack(level) = item level = level + 1 end sub sub WriteAttributeString(item,wert) ' ergänzt eine ID zum aktuellen Element if tagopen then xmlfile.write " id=""" & Quote(wert) & """" else wscript.echo "XMLWriter: Tag not open" wscript.quit(255) end if end sub sub WriteElementString(item,wert) ' wert if tagopen then xmlfile.write ">" : tagopen = false end if xmlfile.write vbcrlf & space(intIndentation*level) & "<" & quote(trim(item)) & ">" & quote(wert) & "" end sub sub WriteEndElement if tagopen then xmlfile.write ">" : tagopen = false end if level = level - 1 xmlfile.write vbcrlf & space(intIndentation*level) & "" end sub private function quote(wert) ' 308060 HOW TO: Locate and Replace Special Characters in an XML File with Visual Basic .NET ' quotes ß . if not isnull(wert) then wert=replace(wert,"&","&") wert=replace(wert,"<","<") wert=replace(wert,">",">") wert=replace(wert,"""",""") wert=replace(wert,"'","'") quote=wert end if end function sub close() : xmlfile.Close : end sub end class class debugwriter private objIE, file, fs, debugfilename,DebugTarget, debuglevel, status, strline private Sub Class_Initialize status = "active" : strline = "" : debugfilename = "" End Sub private Sub Class_Terminate() if isobject(OBJIE) then objie.document.write "" end if if debugfilename <> "" then file.Close end if End Sub public sub start : status = "active": end sub public sub pause : status = "pause" : end sub public property let outfile(wert) if debugfilename <> "" then 'Close existing debug file file.close : file = nothing : fs = nothing end if debugfilename = wert ' open debug file Set fs = CreateObject("Scripting.FileSystemObject") Set file = fs.OpenTextFile(debugfilename, 8, True) end property public property let level (wert) : debuglevel = wert : end property public property let setie (wert) : set objIE = wert : objie.visible = true end property public property let target (wert) DebugTarget = wert end property sub write(strMessage) strline = strline & strMessage end sub Sub writeln(strMessage, intseverity) 'Fügt einen Eintrag in die Log-Datei ein strMessage = strline & strMessage if (status = "active") and (debuglevel >= intseverity) Then if (instr(DebugTarget,"file") <>0) and (debugfilename <> "") then file.Write(Now & ",") Select Case intseverity Case 0 file.Write("Out") Case 1 file.Write("Error") Case 2 file.Write("Warning") Case 3 file.Write("Information") Case Else file.Write("Debug"&intseverity) End Select file.WriteLine("," & strMessage) end if if (instr(DebugTarget,"eventlog") <>0) then dim objWSHShell Set objWSHShell = Wscript.CreateObject("Wscript.Shell") Select Case intseverity Case 0 objWSHShell.LogEvent 0, strMessage ' Const EVENT_SUCCESS = 0 Case 1 objWSHShell.LogEvent 1, strMessage ' const EVENT_ERROR = 1 Case 2 objWSHShell.LogEvent 2, strMessage ' Const EVENT_WARNING = 2 Case else objWSHShell.LogEvent 4, strMessage ' Const EVENT_INFO = 4 End Select end if if (instr(DebugTarget,"console") <>0) then Select Case intseverity Case 0 wscript.echo now() & ",OUT :" & strMessage Case 1 wscript.echo now() & ",ERR :" & strMessage Case 2 wscript.echo now() & ",WARN:" & strMessage Case 3 wscript.echo now() & ",INFO:" & strMessage Case Else wscript.echo now() & ",DBG" & intseverity & ":" & strMessage End Select end if if (instr(DebugTarget,"ie") <>0) then dim strieline if not isobject(objIE) then Set objIE = CreateObject("InternetExplorer.Application") objIE.navigate("about:blank") objIE.visible = true Do While objIE.Busy WScript.Sleep 50 Loop objIE.document.write "DebugWriter Output" objIE.document.write "" end if strieline = "" Select Case intseverity Case 0 strieline = strieLine & "" Case 1 strieline = strieLine & "" Case 2 strieline = strieLine & "" Case 3 strieline = strieLine & "" Case Else strieline = strieLine & "" End Select strieline = strieline & "" objIE.document.write cstr(strieline) end if if (instr(DebugTarget,"mom") <>0) then scriptContext.echo now() &","& intseverity &":"& strline & strMessage end if end if ' if status = active strline = "" End Sub end class sub ForceCScript If InStr(1,WScript.FullName,"cscript",vbTextCompare) = 0 Then ' Prüfung ob mit CSCRIPT gestartet wurde wscript.echo "Bitte mit CSCRIPT aufrufen" wscript.quit (255) end if end sub Sub abbruch(info,waittime) ' usage: call abbruch ("Script abbrechen" ,5) dim WshShell, result Set WshShell = CreateObject("WScript.Shell") result = WshShell.Popup("Continue script at position "& vbcrlf & info & vbcrlf & "Waiting "&waittime&" Seconds", waittime, "Stop Script", 33) 'OKCancel(1) + Question (32) If result = 2 Then WScript.echo "Abbruch durch Anwender (Exitcode = 255)" WScript.Quit(255) End If End Sub
TimeintseverityDescription
" & now () & "OUTERRWARNINFODBG"&intseverity&"" & strmessage & "