Verify Test MB WA

Verify_Test_Mailboxes.WriteAction (WriteActionModuleType)

Element properties:

TypeWriteActionModuleType
IsolationAny
AccessibilityInternal
RunAsSystem.PrivilegedMonitoringAccount
InputTypeSystem.BaseData

Member Modules:

ID Module Type TypeId RunAs 
Script WriteAction Microsoft.Windows.ScriptWriteAction Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
ListOfServersExcludedFromTestMailboxAlertstring$Config/ListOfServersExcludedFromTestMailboxAlert$List Of Servers Excluded From Test Mailbox Alert
TimeoutSecondsint$Config/TimeoutSeconds$Timeout Seconds

Source Code:

<WriteActionModuleType ID="Verify_Test_Mailboxes.WriteAction" Accessibility="Internal" RunAs="System!System.PrivilegedMonitoringAccount" Batching="false">
<Configuration>
<xsd:element name="TargetNetbiosComputer" type="xsd:string"/>
<xsd:element name="ListOfServersExcludedFromTestMailboxAlert" type="xsd:string"/>
<xsd:element name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="ListOfServersExcludedFromTestMailboxAlert" Selector="$Config/ListOfServersExcludedFromTestMailboxAlert$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="Script" TypeID="Windows!Microsoft.Windows.ScriptWriteAction">
<ScriptName>Verify_Test_Mailboxes.vbs</ScriptName>
<Arguments>$Config/TargetNetbiosComputer$ $Config/ListOfServersExcludedFromTestMailboxAlert$</Arguments>
<ScriptBody><Script>
'Copyright (c) Microsoft Corporation. All rights reserved.
'*************************************************************************
' $ScriptName: "Common" $
'
' Purpose: To have one place for common stuff across various Exchange VBScripts
'
' $File: Common.vbs $
'*************************************************************************
' Option Explicit

SetLocale("en-us")

Dim EVENT_SOURCE
EVENT_SOURCE = "Exchange MOM"

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

'=============
'Error Constants
'=============
Const ERROR_FILE_NOT_FOUND = -2147024894 'win32 error: 0x80070002

'=============
'Other Constants
'=============
Const MAX_LONG = 2147483647
Const MIN_LONG = -2147483648

'=============
'Initialize MOM Scripting Variables
'=============
Dim oAPI
Set oAPI = CreateObject("Mom.ScriptAPI")
If Err &lt;&gt; 0 Then
Wscript.Quit -1
End If

'=============
'Helper methods
'=============
' Method: CreateEvent
' Description: Logs Event
' Parameters: source, eventId, eventtype(error/warning/info/success), errormsg
'=============
Sub CreateEvent(lngEventID, lngEventType, strMsg)
Call oAPI.LogScriptEvent(EVENT_SOURCE, lngEventID, lngEventType, strMsg)
End Sub

'=============
' Method: HResultToString
' Description: Returns hresult value in string format 0x00000000(0)
' Parameters: hresult
'=============
Function HResultToString(hresult)
HResultToString = "0x" &amp; Hex(hresult) &amp; "(" &amp; hresult &amp; ")"
End Function

'=============
' Method: RegRead
' Description: Returns registry location value
' Parameters: strKey
'=============
Function RegRead(strKey)
On Error Resume Next
RegRead = "..."

Dim objShell
Set objShell = CreateObject("WScript.Shell")
RegRead = objShell.RegRead(strKey)
Set objShell = Nothing
End Function

'=============
' Method: ConvertDateTime
' Description: Returns datetime as formatted string
' Parameters: dtDateTime
'=============
Function ConvertDateTime(dtDateTime)
Dim objDate, objTime
objDate = DateSerial(Left(dtDateTime, 4), Mid(dtDateTime, 5, 2), Mid(dtDateTime, 7, 2))
objTime = TimeSerial(Mid(dtDateTime, 9, 2), Mid(dtDateTime, 11, 2), Mid(dtDateTime, 13, 2))

ConvertDateTime = FormatDateTime(objDate) &amp; " " &amp; FormatDateTime(objTime)
End Function

'=============
' Method: IsWMIRunning
' Description: Returns true/false
' Parameters: -
'=============
Function IsWMIRunning()
Dim objWMI

On Error Resume Next
Set objWMI = GetObject("winmgmts:root\cimv2")
If Err Then
IsWMIRunning = False
CreateEvent _
9013, _
EVENT_TYPE_ERROR, _
"The 'Windows Management Instrumentation' service (WinMgmt.exe) was not running when MOM tried to run a script that is dependent on this service. Check if the start up mode of this service is not set to 'disabled'."
Else
IsWMIRunning = True
End If

End Function

'=============
' Method: WMIExecQuery
' Description: Returns an object of type SWbemObjectSet
' Parameters:
' sNamespace - A WMI Namespace (ex. winmgmts:\\COMPUTERNAME\ROOT\cimv2).
' sQuery - A SQL Query (ex. SELECT * FROM Win32_OperatingSystem)
' iAlert - To echo/raise error
'=============
Function WMIExecQuery(sNamespace, sQuery, iAlert)
Dim oWMI, oQuery
Dim nErrNumber, sErrDescription
Dim nInstanceCount

On Error Resume Next
Set oWMI = GetObject(sNamespace)
On Error Goto 0

If IsEmpty(oWMI) And iAlert &lt;&gt; 0 Then
WScript.Echo "Unable to open WMI Namespace " &amp; sNamespace
Err.Raise 9100, "Unable to open WMI Namespace " &amp; sNamespace, "Check to see if the WMI service is enabled and running, and ensure this WMI namespace."
End If

On Error Resume Next
Set oQuery = oWMI.ExecQuery(sQuery)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0

If (IsEmpty(oQuery) Or nErrNumber &lt;&gt; 0) And iAlert &lt;&gt; 0 Then
WScript.Echo "The Query '" &amp; sQuery &amp; "' returned an invalid result set. Error:" &amp; nErrNumber &amp; ", " &amp; sErrDescription &amp; "."
Err.Raise 9100, "The Query '" &amp; sQuery &amp; "' returned an invalid result set.", "Please check to see if this is a valid WMI Query. Error:" &amp; nErrNumber &amp; ", " &amp; sErrDescription &amp; "."
End If

'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
nInstanceCount = oQuery.Count
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0

If nErrNumber &lt;&gt; 0 And iAlert &lt;&gt; 0 Then
WScript.Echo "The Query '" &amp; sQuery &amp; "' did not return any valid instances. Error:" &amp; nErrNumber &amp; ", " &amp; sErrDescription &amp; "."
Err.Raise 9100, "The Query '" &amp; sQuery &amp; "' did not return any valid instances.", "Please check to see if this is a valid WMI Query. Error:" &amp; nErrNumber &amp; ", " &amp; sErrDescription &amp; "."
End If

Set WMIExecQuery = oQuery
Set oQuery = Nothing
Set oWMI = Nothing
End Function

'=============
' Method: IsRunningAsSystem
' Description: Returns true/false
' Parameters: -
' Comments: If IsRunningAsSystem is False the caller should check if there is any error (If Err Then ...).
'=============
Function IsRunningAsSystem
Dim WshNetwork
Dim WMISystemAcct

IsRunningAsSystem = False

Set WshNetwork = CreateObject("WScript.Network")

' Use the well-known SID of the system account ("S-1-5-18") to get the correspondent object
Set WMISystemAcct = GetObject("WinMgmts:root/cimv2:Win32_SID='S-1-5-18'")

' WshNetwork.UserName gives the account running the current thread
' WMISystemAcct.AccountName gets the localized name of the system account

' No worries with string case in the comparsion below since, if the account is
' system, the name is extracted from the same location for both objects
If WshNetwork.UserName = WMISystemAcct.AccountName Then
IsRunningAsSystem = True
End If
End Function

'=============
'=============
'Exchange specific Helper methods
'=============
'=============

'=============
' Method: GetNamingContext
' Description: Returns propertyValue from rootDSE object
' Parameters: strPropertyName
'=============
Function GetNamingContext(strPropertyName)
GetNamingContext = ""

Dim IADsRootDSE
Set IADsRootDSE = GetObject("LDAP://rootDSE")

GetNamingContext = IADsRootDSE.Get(strPropertyName)
Set IADsRootDSE = Nothing
End Function

'=============
' Method: GetRootGC
' Description: Returns RootGC
' Parameters: -
'=============
Function GetRootGC()
Dim oGCCollection, oGC
Set oGCCollection = GetObject("GC:")
For each oGC in oGCCollection
Set GetRootGC = oGC
Next
End Function

'=============
' Method: GetCNValue
' Description: -
' Parameters: iOcurr, strData
'=============
Function GetCNValue(iOcurr, strData)
GetCNValue = GetTokValue(iOcurr, "CN=", ",", strData)
End Function

'=============
' Method: GetTokValue
' Description: -
' Parameters: iOcurr, strStartTok, strEndTok, strData
'=============
Function GetTokValue(iOcurr, strStartTok, strEndTok, strData)
Dim iIni, iEnd, iTokLen
iTokLen = Len(strStartTok)
iIni = 1
While iOcurr &gt; 0 ' Skip to the desired occurence
iIni = InStr(iIni, strData, strStartTok, vbTextCompare) + iTokLen
iOcurr = iOcurr - 1
WEnd
iEnd = InStr(iIni, strData, strEndTok, vbTextCompare)
GetTokValue = Mid(strData, iIni, (iEnd - iIni))
End Function

'=============
' Format Constants
'=============
Dim REC_DELIM, INFO_DELIM, IDENT
REC_DELIM = vbCr
INFO_DELIM = vbCr &amp; vbCr
IDENT = " "

'=============
' Method: OutputInfo
' Description: -
' Parameters: strValues, strProps, iPropsFrom, iLevel, blnHierarchical
' Remarks: Very similar to OutDiskInfo sub in Disk_Space_Problem.vbs
'=============
Function OutputInfo(strValues, strProps, iPropsFrom, iLevel, blnHierarchical)
Dim arrValues, arrProps, strLvl
Dim i

If strValues = "" Then Exit Function

On Error Resume Next
OutputInfo = ""
arrValues = Split(strValues, ";")
arrProps = Split(strProps, ",")

While iLevel &gt; 0
strLvl = strLvl &amp; IDENT
iLevel = iLevel - 1
WEnd

For i = iPropsFrom To UBound(arrProps)
OutputInfo = OutputInfo &amp; strLvl &amp; arrProps(i) &amp; ": " &amp; arrValues(i) &amp; REC_DELIM
If i = iPropsFrom and blnHierarchical Then strLvl = strLvl &amp; IDENT
Next
On Error GoTo 0
End Function


'Copyright (c) Microsoft Corporation. All rights reserved.
'*************************************************************************
' $ScriptName: "Common ADO stuff" $
'
' Purpose: To have one place for common stuff across various Exchange VBScripts:
' Disk_Space_Problem
' Verify_If_SSL_Should_Be_Required
' Collect_Public_Folder_Statistics
' Verify_Test_Mailboxes
' Collect_Number_Of_Mailboxes_Per_Server
' Collect_Server_Information
'
' $File: Common_ADO.vbs $
'*************************************************************************
Dim objADOConn, objADOComm

'=========================================================
Sub InitializeGlobalObjects()
' Create the ADO objects to run the query
Set objADOConn = CreateObject("ADODB.Connection")
objADOConn.Provider = "ADsDSOObject"
objADOConn.Open "AD Provider"

Set objADOComm = CreateObject("ADODB.Command")
Set objADOComm.ActiveConnection = objADOConn
objADOComm.Properties("Page Size") = 1000 ' The page size needs to be specified or the function NumberOfEntries will fail
objADOComm.Properties("Timeout") = 30 'seconds
objADOComm.Properties("Cache Results") = false 'do not cache the result set
End Sub

'=========================================================
Sub ReleaseGlobalObjects()
Set objADOConn = Nothing
Set objADOComm = Nothing
End Sub

'=========================================================
Sub GetADSIInfo(strProps, strLDAPQuery, strRes, strFieldDelim, strRecordDelim)
Dim objQueryResult, objIADs, strProp, Values, strValue

objADOComm.CommandText = strLDAPQuery
Set objQueryResult = objADOComm.Execute

While not objQueryResult.eof
Set objIADs = GetObject(objQueryResult.fields(0))

For each strProp in Split(strProps, ",")
On Error Resume Next
Values = objIADs.Get(strProp)
If Err = &amp;h8000500D Then ' value not in the property cache
objIADs.GetInfoEx Array(strProp), 0
Values = objIADs.Get(strProp)
End If
On Error Goto 0

Select Case VarType(Values)
Case 9 ' Object
If Values Is Nothing Then
strValue = "&lt;not set&gt;"
Else
strValue = Values
End If
Case 8204 ' VT_ARRAY + VT_VARIANT
strValue = CStr(NumberOfEntries(objIADs.AdsPath, strProp))
Case Else
strValue = Values
End Select
strRes = strRes &amp; strValue &amp; strFieldDelim
Next

strRes = Left(strRes, Len(strRes) - 1) &amp; strRecordDelim
objQueryResult.MoveNext
WEnd
End Sub

'=========================================================
Function NumberOfEntries(ldapPath, ldapProp)
Dim rs, iStart

NumberOfEntries = 0
iStart = 0

Do
objADOComm.CommandText = "SELECT '" &amp; ldapProp &amp; ";range=" &amp; iStart &amp; "-*' FROM '" &amp; Replace(ldapPath, "'", "''") &amp; "'"
Set rs = objADOComm.Execute()
If (Not rs.EOF) Then
rs.MoveFirst()
iStart = iStart + objADOComm.Properties("Page Size")
If 8204 = VarType(rs.Fields(0).Value) Then
NumberOfEntries = NumberOfEntries + UBound(rs.Fields(0).Value) - LBound(rs.Fields(0).Value) + 1
Else
NumberOfEntries = iStart
End If
End If
Loop While (NumberOFEntries = iStart) And (Not rs.EOF) And (objADOComm.Properties("Page Size") &gt; 0)

End Function



'Copyright (c) Microsoft Corporation. All rights reserved.
'*************************************************************************
' $ScriptName: "Common Verify scripts: Helper methods" $
'
' Purpose: To have one place for common stuff across various Exchange VBScripts:
' Verify_If_SSL_Should_Be_Required
' Verify_Test_Mailboxes
'
' $File: Common_Verify.vbs $
'*************************************************************************

Function IsExcludedSrv(strExcludedSrv, strSrvName)
Dim oParams, ExcludedSrvArray, ExcludedSrvStr, ExcludedSrv

On Error Resume Next
IsExcludedSrv = False
ExcludedSrvStr = strExcludedSrv

If Not Err Then
ExcludedSrvStr = Replace(ExcludedSrvStr, " ", "")
ExcludedSrvArray = Split(ExcludedSrvStr, ",")

For each ExcludedSrv In ExcludedSrvArray
If StrComp(strSrvName, ExcludedSrv, vbTextCompare) = 0 Then
IsExcludedSrv = True
Exit For
End If
Next
End If

On Error Goto 0
End Function

'Copyright (c) Microsoft Corporation. All rights reserved.
'*******************************************************************************
' $ScriptName: "GetLongParameter" $
'
' Purpose: Common function used by Collect_Server_Information.vbs and Verify_Test_Mailboxes.vbs files
'
' $File: FindTestAccounts.vbs $
'*************************************************************************
Const FAILED_TO_FIND_TST_MB_ID = 9026
Const FAILED_TO_FIND_TST_MB_MSG = "Error while querying for the test mailboxes. Detailed information:"

Function FindTestAccounts(strServerName)
'
' What is returned? Semicolon ";" delimeted list of:
' 1. Account name
' 2. Mdb name
' 3. Storage Group Name
' 4. Server Name
'
Dim testServerMailbox_RegPath
Dim mdbMailboxNames_RegPath

Dim sRegValue, sAccountFromRegistry, arrAccounts, numberOfAccounts, index

Dim strMailboxes : strMailboxes = ""

Dim sCommand
Dim oConnect, command, rs, i
Dim objADsPathname

Dim strAccount, strMdb, strStorageGroup, strServer, strDisplayName

If strServerName = "" Or IsEmpty(strServerName) Or IsNull(strServerName) Then
FindTestAccounts = Empty
Exit Function
End If

testServerMailbox_RegPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange MOM\Accounts\" &amp; strServerName &amp; "\TestServerMailbox"
mdbMailboxNames_RegPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange MOM\Accounts\" &amp; strServerName &amp; "\MDBMailboxNames"
On Error Resume next

'Retrieve TestServerMailbox value
sRegValue = RegRead(testServerMailbox_RegPath)
If Err Then
If not (ERROR_FILE_NOT_FOUND = Err.Number) Then
On Error Goto 0
Err.Raise
Else
sRegValue = strServerName &amp; "MOM"
Err.Clear
End If
End If

sRegValue = Trim(sRegValue)

'Deals with the case when the value was created but not touched
' in which RegRead will return the registry path or empty
If (sRegValue = testServerMailbox_RegPath) Or (sRegValue = "") Then
sRegValue = strServerName &amp; "MOM"
End If

sAccountFromRegistry = sRegValue

'Retrieve mdbMailboxNames value
sRegValue = RegRead(mdbMailboxNames_RegPath)
If Err Then
If not (ERROR_FILE_NOT_FOUND = Err.Number) Then
On Error Goto 0
Err.Raise
Else
sRegValue = strServerName &amp; "MOM*"
Err.Clear
End If
End If

sRegValue = Trim(sRegValue)

'Deals with the case when the value was created but not touched
' in which RegRead will return the registry path or empty
If (sRegValue = testServerMailbox_RegPath) Or (sRegValue = "") Then
sRegValue = strServerName &amp; "MOM*"
End If

sAccountFromRegistry = sAccountFromRegistry &amp; "," &amp; sRegValue

arrAccounts = Split(sAccountFromRegistry, ",")
numberOfAccounts = UBound(arrAccounts) + 1

For index = 0 to numberOfAccounts-1
arrAccounts(index) = Trim( arrAccounts(index))
Next

If Err Then
CreateEvent _
FAILED_TO_FIND_TST_MB_ID, _
EVENT_TYPE_ERROR, _
FAILED_TO_FIND_TST_MB_MSG &amp; REC_DELIM &amp; "Description: " &amp; Err.Description &amp; REC_DELIM &amp; "Source: " &amp; Err.Source &amp; _
REC_DELIM &amp; "Number: " &amp; HResultToString(Err.Number)
Err.Clear
Exit Function
End If

'Form select statement to query AD to see if the user accounts exist and to get properties such users' homeMDB
sCommand = "SELECT homeMDB, AdsPath, cn, displayName FROM '" &amp; GetRootGC().ADsPath &amp; "' WHERE " &amp; _
" samAccountName='" &amp; arrAccounts(0) &amp; "' AND objectclass='user' AND objectCategory='person' "

If numberOfAccounts &gt; 0 Then
For index = 1 to numberOfAccounts-1
sCommand = sCommand &amp; " OR samAccountName='" &amp; arrAccounts(index) &amp; "' AND objectclass='user' AND objectCategory='person' "
Next
End If

sCommand = sCommand &amp; " ORDER BY samAccountName "

set oConnect = CreateObject("ADODB.Connection")
oConnect.Provider = "ADsDSOObject"
oConnect.Open()

set command = CreateObject("ADODB.Command")
command.ActiveConnection = oConnect
command.CommandText = sCommand
command.Properties("Page Size") = 100
command.Properties("Timeout") = 20 'seconds
command.Properties("searchscope") = 2 'ADS_SCOPE_SUBTREE
command.Properties("Chase referrals") = 96 ' 0x60 = 0x20 | 0x40 ADS_CHASE_REFERRALS_ALWAYS
command.Properties("Cache Results") = false 'do not cache the result set

set rs = command.Execute()
If Err Then
CreateEvent _
FAILED_TO_FIND_TST_MB_ID, _
EVENT_TYPE_ERROR, _
FAILED_TO_FIND_TST_MB_MSG &amp; REC_DELIM &amp; "Description: " &amp; Err.Description &amp; REC_DELIM &amp; "Source: " &amp; _
Err.Source &amp; REC_DELIM &amp; "Number: " &amp; HResultToString(Err.Number)
Err.Clear
Exit Function
End If

set objADsPathname = CreateObject("Pathname")

If not rs.EOF then
rs.MoveFirst
While not rs.EOF
If Err Then
CreateEvent _
FAILED_TO_FIND_TST_MB_ID, _
EVENT_TYPE_ERROR, _
FAILED_TO_FIND_TST_MB_MSG &amp; REC_DELIM &amp; "Description: " &amp; Err.Description &amp; REC_DELIM &amp; "Source: " &amp; _
Err.Source &amp; REC_DELIM &amp; "Number: " &amp; HResultToString(Err.Number)
Err.Clear
Exit Function
End If

strMdb = ""
strStorageGroup = ""
strServer = ""
strDisplayName = ""

For i = 0 to rs.Fields.Count-1
If rs.Fields(i).Name = "cn" Then
strAccount = rs.Fields(i).Value
End If

If rs.Fields(i).Name = "homeMDB" Then
If rs.Fields(i).Value &lt;&gt; "" Then
objADsPathname.Set rs.Fields(i).Value, 4
objADsPathname.EscapedMode = 4

strMdb = objADsPathname.GetElement(0)
If Len(strMdb) &gt; 3 Then strMdb = Right(strMdb, Len(strMdb) - 3)

strStorageGroup = objADsPathname.GetElement(1)
If Len(strStorageGroup) &gt; 3 Then strStorageGroup = Right(strStorageGroup, Len(strStorageGroup) - 3)

strServer = objADsPathname.GetElement(3)
If Len(strServer) &gt; 3 Then strServer = Right(strServer, Len(strServer) - 3)
End If
End If

If rs.Fields(i).Name = "displayName" Then
strDisplayName = rs.Fields(i).Value
End If
Next

If strAccount &lt;&gt; "" Then
strMailboxes = strMailboxes _
&amp; strAccount &amp; ";" _
&amp; strMdb &amp; ";" _
&amp; strStorageGroup &amp; ";" _
&amp; strServer &amp; ";" _
&amp; strDisplayName &amp; ";"
End If

rs.MoveNext()
Wend
End If

FindTestAccounts = strMailboxes
End Function


'Copyright (c) Microsoft Corporation. All rights reserved.
'***********************************************************************************************
' $ScriptName: "Verify Test Mailboxes" $
'
' Purpose: Verify the state of the test mailboxes used by the Exchange MP
'
' Parameters:
'
' "ListOfServersExcludedFromTestMailboxAlert" = comma delimited list of the servers that the customer
' does not want to be alerted about test mailbox issues
'
' Events created by this script:
' SOURCE ID TYPE DESCRIPTION
' Exchange MOM 9023 warning No test mailbox for the specified MDBs
' Exchange MOM 9024 error No one test mailbox for the specified server
' Exchange MOM 9025 error More than one test mailbox in the same MDB
' Exchange MOM 9030 error Accounts without the correspondent Exchange mailbox
' Exchange MOM 9035
' Exchange MOM 9036
'
' $File: Verify_Test_Mailboxes.vbs $
'***********************************************************************************************
'Event ID Constants
EVENT_SOURCE = "Verify Test Mailboxes"
Const NO_TST_MB_FOR_MDB_ID = 9023
Const NO_TST_MB_FOR_MDB_MSG = "There is no MOM test mailbox for the following mailbox databases (MDBs): "

Const NO_TST_MDB_FOR_SVR_ID = 9024
Const NO_TST_MDB_FOR_SVR_MSG = "This Exchange Server does not have any MOM test mailboxes"

Const REDUNDANT_TST_MB_ID = 9025
Const REDUNDANT_TST_MB_MSG = "There is more than one test mailbox in the same MDB. Detailed information:"

Const TST_MB_ON_WRONG_SRV_ID = 9027
Const TST_MB_ON_WRONG_SRV_MSG = "Some MOM test mailboxes are residing on the wrong server. Move the mailboxes to the correct server or delete them. List of mailboxes residing on wrong servers: "

Const NO_MB_FOR_ACCT_ID = 9030
Const NO_MB_FOR_ACCT_MSG = "The accounts listed below do not have an Exchange mailbox and therefore cannot be used by the Exchange Management Pack. It also possible that the account running the script does not have the appropriate permissions to get this information from the Global Catalog."

Const TST_MB_NOT_INSPECTED_ID = 9035
Const TST_MB_NOT_INSPECTED_MSG = "The Global Catalog indicates that the accounts below are located on the correct server. However queries to the Active Directory did not return the storage group or mailbox store (MDB) where the mailboxes of these accounts are supposed to reside. Check if the account running the script has the appropriate permissions to access information about this Exchange server on the Active Directory. List of mailboxes for which the storage group or mailbox store (MDB) was not returned from the Active Directory: "

Const NO_AD_SRV_OBJ_ID = 9036
Const NO_AD_SRV_OBJ_MSG = "Failed to obtain the Exchange server information from the Active Directory. Check if the account running the script has the appropriate permissions to get this information from the Active Directory."

Const EXCLUDED_SRV_INC = 10

' Global objects
Dim strOutput

' V3 Changes Start
' Hardcoding some of the params for the time being

Dim TargetNetbiosComputer
Dim ListOfServersExcludedFromTestMailboxAlert

if WScript.Arguments.Count = 2 then
TargetNetbiosComputer = WScript.Arguments(0)
ListOfServersExcludedFromTestMailboxAlert = WScript.Arguments(1)
else
WScript.quit()
end if

'V3 Changes End
GetEx2kInfoFromAD TargetNetbiosComputer, strOutput

' =====================================================================
' Method: GetEx2kInfoFromAD
'=================================================================================
Sub GetEx2kInfoFromAD(strComputer, strOutput)
Dim strScope, strDN, strSearchFilter, strQuery
Dim strSrvProps, strSrvs, strSrv

Dim strMailboxes, strMailboxSplit, nMailboxes, i, strMailboxArray, validTestMailbox

Dim nValidTestMailboxesPerServer, strMDBWithoutTstMailbox, blnIsFrontEnd
Dim strSGProps, strSGs, strSG, strStorageGroupName

Dim nValidTestMailboxesPerMDB, strRedundantMomTstMailboxes
Dim strMDBProps, strMDBs, strMDB, strMdbName

Dim IsExcludedInc
Dim strTstMailboxOnWrongServer, strNoMailboxForAccount
Dim strTstMailboxSGOrMDBNotOpened

' Constants to access properties in the mailboxes array
Const ACCOUNT = 0
Const MDB = 1
Const STORAGE_GROUP = 2
Const SERVER = 3
Const DISPLAYNAME = 4
Const CHECKED = 5
Const RETURNED_PROPERTIES = 5
Const NUM_OF_PROPERTIES = 6 ' ATTENTION: Include any new property above this item and update its value

InitializeGlobalObjects

strScope = "subTree"
strDN = "&lt;LDAP://" &amp; GetNamingContext("configurationNamingContext") &amp; "&gt;"
strSearchFilter = "(&amp;(objectCategory=msExchExchangeServer)(cn=" &amp; strComputer &amp; "))"
strQuery = strDN &amp; ";" &amp; strSearchFilter &amp; ";*;" &amp; strScope
strSrvProps = "distinguishedName,serverRole"
strSrvs = ""

GetADSIInfo strSrvProps, strQuery, strSrvs, ";", REC_DELIM

If strSrvs = "" Then
CreateEvent NO_AD_SRV_OBJ_ID, EVENT_TYPE_WARNING, NO_AD_SRV_OBJ_MSG
End If

For each strSrv in Split(strSrvs, REC_DELIM)
If strSrv = "" Then Exit For

' Collect info about the test mailboxe accounts
strMailboxes = FindTestAccounts(strComputer)
If IsEmpty(strMailboxes) Then Exit Sub

If strMailboxes &lt;&gt; "" Then
strMailboxSplit = Split(strMailboxes, ";", -1, 1)
nMailboxes = UBound(strMailboxSplit)/RETURNED_PROPERTIES ' FindTestAccounts returns 5 props for each MDB

Redim strMailboxArray(nMailboxes, NUM_OF_PROPERTIES) ' We store one property more in the array
For i = 0 to nMailboxes-1
strMailboxArray(i, ACCOUNT) = strMailboxSplit(RETURNED_PROPERTIES*i + ACCOUNT)
strMailboxArray(i, MDB) = strMailboxSplit(RETURNED_PROPERTIES*i + MDB)
strMailboxArray(i, STORAGE_GROUP) = strMailboxSplit(RETURNED_PROPERTIES*i + STORAGE_GROUP)
strMailboxArray(i, SERVER) = strMailboxSplit(RETURNED_PROPERTIES*i + SERVER)
strMailboxArray(i, DISPLAYNAME) = strMailboxSplit(RETURNED_PROPERTIES*i + DISPLAYNAME)
strMailboxArray(i, CHECKED) = False
Next ' i = 0 to nMailboxes-1
End If

nValidTestMailboxesPerServer = 0
strMDBWithoutTstMailbox = ""
Select Case Split(strSrv, ";")(1) ' Server Role
Case "0"
blnIsFrontEnd = False
Case "1"
blnIsFrontEnd = True
Case Else
blnIsFrontEnd = Empty
End Select

' Get the Storage group info
strDN = "&lt;LDAP://" &amp; Left(strSrv, InStr(strSrv, ";") -1) &amp; "&gt;"
strSearchFilter = "(&amp;(objectCategory=msExchStorageGroup)(|(!msExchRestore=*)(!msExchRestore=TRUE)))"
strQuery = strDN &amp; ";" &amp; strSearchFilter &amp; ";*;" &amp; strScope
strSGProps = "distinguishedName,name"
strSGs = ""

GetADSIInfo strSGProps, strQuery, strSGs, ";", REC_DELIM

For each strSG in Split(strSGs, REC_DELIM)
If strSG = "" Then Exit For

strStorageGroupName = Split(strSG, ";")(1)

' Get the Private MDBs info
strDN = "&lt;LDAP://" &amp; Left(strSG,InStr(strSG,";") - 1) &amp; "&gt;"
strSearchFilter = "(objectCategory=msExchPrivateMDB)"
strQuery = strDN &amp; ";" &amp; strSearchFilter &amp; ";*;" &amp; strScope
strMDBProps = "name"
strMDBs = ""

GetADSIInfo strMDBProps, strQuery, strMDBs, ";", REC_DELIM
For each strMDB in Split(strMDBs, REC_DELIM)
If strMDB = "" Then Exit For

strMdbName = strMDB
validTestMailbox = 0
nValidTestMailboxesPerMDB = 0
strRedundantMomTstMailboxes = ""

For i = 0 to nMailboxes-1
If (StrComp(strMailboxArray(i,SERVER),strComputer,vbTextCompare) = 0) and _
(StrComp(strMailboxArray(i,STORAGE_GROUP),strStorageGroupName,vbTextCompare) = 0) and _
(StrComp(strMailboxArray(i,MDB),strMdbName,vbTextCompare) = 0) Then

strMailboxArray(i, CHECKED) = True
validTestMailbox = 1
nValidTestMailboxesPerMDB = nValidTestMailboxesPerMDB + 1
strRedundantMomTstMailboxes = strRedundantMomTstMailboxes &amp; strMailboxArray(i,ACCOUNT) &amp; REC_DELIM
End If
Next ' i = 0 to nMailboxes-1

If (validTestMailbox = 0) Then
If IsEmpty(strMailboxes) Then
' Do Nothing "&lt;FAILED TO QUERY TEST MAILBOXES&gt;"
Else
strMDBWithoutTstMailbox = strMDBWithoutTstMailbox &amp; "MDB """ &amp; strMdbName &amp; """ on storage group """ &amp; strStorageGroupName &amp; _
""" on server " &amp; strComputer &amp; REC_DELIM
End If
ElseIf (not blnIsFrontEnd) and (nValidTestMailboxesPerMDB &gt; 1) Then
CreateEvent _
REDUNDANT_TST_MB_ID, _
EVENT_TYPE_ERROR, _
REDUNDANT_TST_MB_MSG &amp; INFO_DELIM &amp; "Exchange server: " &amp; strComputer &amp; REC_DELIM &amp; _
"Storage group: " &amp; strStorageGroupName &amp; REC_DELIM &amp; "MDB: " &amp; _
strMdbName &amp; INFO_DELIM &amp; "Test mailboxes on this MDB: " &amp; REC_DELIM &amp; strRedundantMomTstMailboxes
End If

nValidTestMailboxesPerServer = nValidTestMailboxesPerServer + nValidTestMailboxesPerMDB
Next ' For each private MDB
Next ' For each Storage Group

' Test mail boxes events
If not (blnIsFrontEnd) Then
If (strMDBWithoutTstMailbox &lt;&gt; "") Then
If IsExcludedSrv(ListOfServersExcludedFromTestMailboxAlert, strComputer) Then
IsExcludedInc = EXCLUDED_SRV_INC
Else
IsExcludedInc = 0
End If

CreateEvent _
NO_TST_MB_FOR_MDB_ID + IsExcludedInc, _
EVENT_TYPE_WARNING, _
NO_TST_MB_FOR_MDB_MSG &amp; INFO_DELIM &amp; strMDBWithoutTstMailbox

If nValidTestMailboxesPerServer = 0 Then
CreateEvent NO_TST_MDB_FOR_SVR_ID + IsExcludedInc, EVENT_TYPE_ERROR, NO_TST_MDB_FOR_SVR_MSG
End If
End If
End If

' Check mail boxes residing on the wrong SERVER
If nValidTestMailboxesPerServer &lt; nMailboxes Then
strTstMailboxOnWrongServer = ""
strNoMailboxForAccount = ""

For i = 0 to nMailboxes-1
If not(strMailboxArray(i, CHECKED)) Then
If strMailboxArray(i,MDB) = "" Then
strNoMailboxForAccount = strNoMailboxForAccount &amp; "The account """ &amp; strMailboxArray(i,ACCOUNT) &amp; """ does not have an Exchange mailbox" &amp; REC_DELIM
Else
' If the SG or MDB of this account was not opened it will not be marked as checked although
' it is really residing on this computer
If StrComp(strMailboxArray(i,SERVER),strComputer,vbTextCompare) &lt;&gt; 0 Then

strTstMailboxOnWrongServer = strTstMailboxOnWrongServer &amp; "MOM test mailbox """ &amp; strMailboxArray(i,ACCOUNT) &amp; """ is residing on server """ &amp; strMailboxArray(i,SERVER) &amp; _
""" in Storage Group """ &amp; strMailboxArray(i,STORAGE_GROUP) &amp; """ and Database """ &amp; strMailboxArray(i,MDB) &amp; """ instead of """ &amp; _
strComputer &amp; """" &amp; INFO_DELIM
Else
strTstMailboxSGOrMDBNotOpened = strTstMailboxSGOrMDBNotOpened &amp; "MOM test mailbox """ &amp; strMailboxArray(i,ACCOUNT) &amp; """ was not fully inspected since its " &amp; _
"Storage Group (""" &amp; strMailboxArray(i,STORAGE_GROUP) &amp; """) or Database (""" &amp; strMailboxArray(i,MDB) &amp; """) was not enumerated as part of the current server in an " &amp; _
"Active Directory query." &amp; INFO_DELIM
End If
End If
End If
Next ' i = 0 to nMailboxes-1

If strTstMailboxOnWrongServer &lt;&gt; "" Then
CreateEvent TST_MB_ON_WRONG_SRV_ID, EVENT_TYPE_ERROR, TST_MB_ON_WRONG_SRV_MSG &amp; INFO_DELIM &amp; strTstMailboxOnWrongServer
End If

If strTstMailboxSGOrMDBNotOpened &lt;&gt; "" Then
CreateEvent TST_MB_NOT_INSPECTED_ID, EVENT_TYPE_ERROR, TST_MB_NOT_INSPECTED_MSG &amp; INFO_DELIM &amp; strTstMailboxSGOrMDBNotOpened
End If

If strNoMailboxForAccount &lt;&gt; "" Then
CreateEvent NO_MB_FOR_ACCT_ID, EVENT_TYPE_ERROR, NO_MB_FOR_ACCT_MSG &amp; INFO_DELIM &amp; strNoMailboxForAccount
End If
End If
Next

ReleaseGlobalObjects
End Sub

</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="Script"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>