Exchange 2003 Server Role attribute Discovery

Microsoft.Exchange.ServerRole.2003.Discovery (Discovery)

This rule discovers all attributes of an Exchange 2003 server

Knowledge Base article:

Summary

This discovery rule discovers the Exchange 2003 Server Role attributes.

Configuration

There is no configuration required. To disable local Exchange 2003 Server role discovery disable (override) the rule “Exchange 2003 Server Initial Discovery”.

Element properties:

TargetMicrosoft.Exchange.ServerRole.2003
EnabledTrue
Frequency3600
RemotableFalse

Object Discovery Details:

Discovered Classes and their attribuets:

Member Modules:

ID Module Type TypeId RunAs 
DiscoveryDataSource DataSource System.CommandExecuterDiscoveryDataSource Default

Source Code:

<Discovery ID="Microsoft.Exchange.ServerRole.2003.Discovery" Enabled="onEssentialMonitoring" Target="Microsoft.Exchange.ServerRole.2003" ConfirmDelivery="false" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Microsoft.Exchange.ServerRole.2003">
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="DistinguishedName"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="RoutingGroup"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="IsFrontEnd"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="AdminGroup"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="Organization"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="DisplayName"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="Name"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="Version"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="VersionGroup"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="NumMailboxes"/>
<Property TypeID="Microsoft.Exchange.ServerRole.2003" PropertyID="ADSite"/>
</DiscoveryClass>
</DiscoveryTypes>
<DataSource ID="DiscoveryDataSource" TypeID="System!System.CommandExecuterDiscoveryDataSource">
<IntervalSeconds>3600</IntervalSeconds>
<ApplicationName>%windir%\System32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>$file/DiscoverMicrosoftExchangeServerRole2003.js$ 0 $MPElement$ $Target/Id$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosDomainName$ $Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</CommandLine>
<TimeoutSeconds>300</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>DiscoverMicrosoftExchangeServerRole2003.js</Name>
<Contents><Script>
//Copyright (c) Microsoft Corporation. All rights reserved.
//*************************************************************
// $ScriptName: "Exchange - Local Server Discovery" $
//
// Collects local Exchange server configuration data and
// populates MOM's service discovery tables with it, which
// supplies information to MOM's topology view, state monitoring
// features and add managed servers to appropriate discovery group,
// which is tied to the associated Exchange computer group in MOM,
// required for pushing out the MP rules.
//
//
// Events created by this script:
// SOURCE ID TYPE DESCRIPTION
// Exchange MOM 24100 inform Exchange Local Server Discovery - starting
// Exchange MOM 24101 inform Exchange Local Server Discovery - finished
// Exchange MOM 24102 error Service discovery data for the Exchange server '%0' is omitted due to error
// Exchange MOM 24103 warning Error querying Exchange WMI class: %0
// Exchange MOM 24104 warning Error connecting to or querying Active Directory using ADSI. Error: %0
// Exchange MOM 24105 warning An unexpected error occurred. Error: %0
// Exchange MOM 24106 warning Error in translating a computer's distinguishedName to NetBiosName format. Service discovery data for server '%0' is omitted." + "\n" + "Error number:%1" + "\n" + "Error description:%2
//
// $File: Exchange_Local_Server_Discovery.js $
//
// $Date: 2005/03/31 19:14:09 $ $Revision: 7 $
//*************************************************************

var EVENT_SOURCE = "Exchange MOM";

// Event Constants

// Event Constants
var EVENT_TYPE_SUCCESS = 0;
var EVENT_TYPE_ERROR = 1;
var EVENT_TYPE_WARNING = 2;
var EVENT_TYPE_INFORMATION = 4;

// Event ID Constants
var EVENT_ID_BASE_STATE_OK = 10000;


var START_SERVICE_DISCOVERY_ID = 4100;
var START_SERVICE_DISCOVERY_MSG = "Exchange Local Server Discovery - starting";

var FINISHED_SERVICE_DISCOVERY_ID = 4101;
var FINISHED_SERVICE_DISCOVERY_MSG = "Exchange Local Server Discovery - finished";

var INSTANCE_OMISSION_ID = 4102;
var INSTANCE_OMISSION_MSG = "Service discovery data for the Exchange server '%0' is omitted due to error: %1" + "\n" + "Error number: %2" + "\n" + "Error description: %3";

var WMI_ERROR_ID = 24103;
var WMI_ERROR_MSG = "Error querying Exchange WMI class: %0.\n" + "Error number: %1" + "\n" + "Error description: %2";

var CONNECT_AD_ERROR_ID = 4104;
var CONNECT_AD_ERROR_MSG = "Error connecting to or querying Active Directory using ADSI. Error: %0\n" + "Error number: %1" + "\n" + "Error description: %2";

var UNEXPECTED_ERROR_ID = 4105;
var UNEXPECTED_ERROR_MSG = "An unexpected error occurred. Error: %0" + "\n" + "Error number: %1" + "\n" + "Error description: %2";

var NAMETRANSLATE_ERROR_ID = 4106;
var NAMETRANSLATE_ERROR_MSG = "Error in translating a computer's distinguishedName to NetBiosName format. DN = '%0'." + "\n" + "Error number:%1" + "\n" + "Error description:%2";

var oAPI;
// First we create the script API
oAPI = new ActiveXObject("Mom.ScriptAPI")

// Fetch the parameters
// If the number of arguments is less than 3, quit

var FQDN, NetbiosComputername, ShortNetbiosDomainname,SourceType, SourceId, ManagedEntityId,TargetComputer

if(WScript.Arguments.Unnamed.Count == 6){
SourceType=WScript.Arguments(0) ;
SourceId=WScript.Arguments(1) ;
ManagedEntityId=WScript.Arguments(2);
NetbiosComputername = WScript.Arguments(3) ;
FQDN = WScript.Arguments(4)+"\\"+NetbiosComputername;
TargetComputer= WScript.Arguments(5);
}else{
WScript.quit();
}

function CreateEvent(strSource, lngEventID, lngEventType, strMsg)
{
oAPI.LogScriptEvent(strSource, lngEventID, lngEventType, strMsg);
}

function HResultToString(hresult)
{
return "0x" + (hresult &lt; 0 ? hresult + 0x100000000 : hresult).toString(16).toUpperCase() + "(" + hresult +")";
}


function GetRootGC()
{
var oGCColl = GetObject("GC:");
var enumGCs = new Enumerator(oGCColl);
if (!enumGCs.atEnd())
return enumGCs.item();

return null;
}

///////////////////////////////////////////////
//EventText -Replace escaped character %# with
//elements in the input array "param"
//
//This function assumes a zero base array
// e.g. EventText("%0 is the server. %1 is the client", new Array("Exchange", "Outlook"))
// would return "Exchange is a server. Outlook is a client"
//
// but EventText("%1 is the server. %2 is the client", new Array("Exchange", "Outlook"))
// would return "Outlook is a server. %2 is a client"
function EventText(eventText, param)
{
var index;
for (index in param)
{
eventText = eventText.replace("%"+index, param[index]);
}
return eventText;
}



/////////////////////////////////////////////////////
//GetFQDN
//Returns the FQDN given the NetbiosComputer and
//the NetbiosFullName (Domain\Computer)
//
//It queries the AD for all Computer objects with CN=NetbiosComputer
//and then translate the DN of that object back into Netbios format.
//If the translated format matches NetbiosFullName, then
//return the dNSHostName attribute (which is the FQDN)
function GetFQDN(netBiosComputerName, netBiosFullName)
{
//Constants
var ADS_NAME_INITTYPE_GC = 3;
var ADS_NAME_TYPE_1779 = 1;
var ADS_NAME_TYPE_NT4 = 3;

//local variables
var oConnect, strCommand, command, objRootGC, rs;
var serverDN;
var nameTranslate;
var netBiosNameTranslated = null; //format: "Domain\Server"
var fqdn = null;

try
{
oConnect = new ActiveXObject("ADODB.Connection");
oConnect.Provider = "ADsDSOObject";
oConnect.Open();
command = new ActiveXObject("ADODB.Command");
command.ActiveConnection = oConnect;
objRootGC = GetRootGC();

strCommand = "SELECT distinguishedName, dNSHostName FROM '" + objRootGC.ADsPath + "' WHERE ";
strCommand = strCommand + " objectCategory='Computer' AND cn='" + netBiosComputerName + "'";

command.CommandText = strCommand;
command.Properties("Page Size") = 100;
command.Properties("Timeout") = 10;
command.Properties("searchscope") = 2;
command.Properties("Chase referrals") = 0x20 | 0x40;
command.Properties("Cache Results") = false;
rs = command.Execute();
}
catch(err)
{
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(netBiosFullName, "Encountered problem in GetFQDN when attempting to query the AD", HResultToString(err.number), err.description)));
return null;
}


while (!rs.EOF)
{
try
{
serverDN = rs.Fields("distinguishedName").Value;
}
catch(err)
{
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(UNEXPECTED_ERROR_MSG, new Array("Encountered problem in GetFQDN when accessing the 'distinguishedName' attribute of computer object:'" + netBiosFullName + "'", HResultToString(err.number), err.description)));
rs.MoveNext();
continue;
}

if (null == serverDN || "" == serverDN )
{
rs.MoveNext();
continue;
}
else
{
try
{
nameTranslate = new ActiveXObject("NameTranslate");
nameTranslate.Init(ADS_NAME_INITTYPE_GC, "");
nameTranslate.Set(ADS_NAME_TYPE_1779, serverDN);
netBiosNameTranslated = nameTranslate.Get(ADS_NAME_TYPE_NT4);
//take out an ending $ character (placed by IADsNameTranslate) that's not part of the netBiosName
netBiosNameTranslated = netBiosNameTranslated.substr(0,netBiosNameTranslated.length-1);
}
catch (err)
{
CreateEvent(
EVENT_SOURCE,
NAMETRANSLATE_ERROR_ID,
EVENT_TYPE_WARNING,
EventText(NAMETRANSLATE_ERROR_MSG, new Array(serverDN, HResultToString(err.number), err.description)));
rs.MoveNext();
continue;
}

if (netBiosNameTranslated.toUpperCase() == netBiosFullName.toUpperCase())
{
try
{
fqdn = rs.Fields("dNSHostName").Value;
return fqdn;
}
catch(err)
{
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(UNEXPECTED_ERROR_MSG, new Array("Encountered problem in GetFQDN when accessing the 'dNSHostName' attribute of computer object: '" + serverDN + "'", HResultToString(err.number), err.description)));
rs.MoveNext();
continue;
}
}
}

rs.MoveNext();
}

return null;

}

//////////////////////////
//DiscoverLocalExchangeServers
//
// Return an array of discovered Exchange servers (found within the AD forest)
// and their associated properties (type string):
// 1. fullname (domain\servername) [required]
// 2. name (servername) [required]
// 3. version (e.g. Version 6.5 (Build 6944.4) ) [optional]
// 5. adminGroup (name of administrative group that the Exchange server belongs to) [required]
// 7. routingGroup (name of routing group that the Exchange server belongs to) [required]
// 9. isFrontEnd (if "true" then server is configurated as a Frontend, otherwise "false") [required]
// 10. versionGroup (indicate the server is either "Exchange 2000", "Exchange 2000 Frontend", "Exchange 2003" or "Exchange 2003 Frontend") [required]
// 11. mailboxes (number of mailboxes on the server)
// 12. adSite (the AD site that the server belongs to)
/////////////////////////
function DiscoverLocalExchangeServers()
{
var oConnect, command, objRootDSE, strCommand, rs, wshNetwork, physicalComputer, domain;
var fullname, name, fqdn, distinguishedName, version, org, adminGroup, routingGroupDN, routingGroup, isFrontEnd, versionGroup, adSite, mailboxes, isExchange;
var shell, wmiExchangeMailboxes, adSystemInfo, adPathname;
var REGKEY_NOT_EXIST = -2147024894;

function property(fullname, name, version, org, adminGroup, routingGroup, isFrontEnd, versionGroup, mailboxes, adSite , distinguishedName)
{
this.fullname = fullname;
this.name = name;
this.version = version;
this.org = org;
this.adminGroup = adminGroup;
this.routingGroup = routingGroup;
this.isFrontEnd = isFrontEnd;
this.versionGroup = versionGroup;
this.adSite = adSite;
this.mailboxes = mailboxes;
this.distinguishedName = distinguishedName;
}

fullname = FQDN;
if (null == fullname || 0 == fullname.length)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(UNEXPECTED_ERROR_MSG, new Array("MOM error in DiscoverLocalExchangeServers(): ScriptContext.TargetComputerIdentity returned null or an empty string", "", "")));
return null;
}

name = NetbiosComputername;
if (null == name || 0 == name.length)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(UNEXPECTED_ERROR_MSG, new Array("MOM error in DiscoverLocalExchangeServers(): ScriptContext.TargetNetbiosComputer returned null or an empty string", "", "")));
return null;
}

fqdn = GetFQDN(name, fullname);
if (null == fqdn)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fullname, "GetFQDN cannot find the FQDN for server:'" + fullname + "'", "", "")));

return null;
}

isFrontEnd = 0;
version = null;
adminGroup = null;
routingGroup = null;
versionGroup = null;
adSite = null;
mailboxes = null;

shell = new ActiveXObject("WScript.Shell");
try
{
isExchange = shell.RegRead("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\MSExchangeSA\\ImagePath");
}
catch (err)
{
//If reg key is missing, then it is not an Exchange server
if (err.number == REGKEY_NOT_EXIST)
{
return null;
}
else
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Problem accessing the Registry, in function DiscoverLocalExchangeServers(), to discover existance of Exchange installation. Abort execution.", HResultToString(err.number), err.description)));
return null;
}
}

try
{
oConnect = new ActiveXObject("ADODB.Connection");
oConnect.Provider = "ADsDSOObject";
oConnect.Open();
command = new ActiveXObject("ADODB.Command");
command.ActiveConnection = oConnect;
objRootDSE = GetObject("LDAP://rootDSE");

strCommand = "SELECT adsPath FROM 'LDAP://" + objRootDSE.Get("configurationNamingContext") + "' WHERE ";
strCommand = strCommand +
" objectCategory='msExchExchangeServer' AND cn='" + name + "' " +
" AND networkAddress='ncacn_ip_tcp:" + fqdn + "' AND versionNumber &gt;= 4417";

command.CommandText = strCommand;
command.Properties("Page Size") = 100;
command.Properties("Timeout") = 10;
command.Properties("searchscope") = 2;
command.Properties("Chase referrals") = 0x20 | 0x40;
command.Properties("Cache Results") = false;
rs = command.Execute();
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Encountered problem while querying server object against AD in DiscoverLocalExchangeServer() ",HResultToString(err.number), err.description)));
return null;
}

if (!rs.EOF)
{
try
{
server = GetObject(rs.Fields("adspath").Value);
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Encountered problem in DiscoverLocalExchangeServers() when accessing the 'adsPath' attribute in AD.\n", HResultToString(err.number), err.description)));
return null;
}

try
{
versionGroup = server.Get("versionNumber");
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Encountered problem in DiscoverLocalExchangeServers() when accessing the 'versionNumber' attribute in AD.\n", HResultToString(err.number), err.description)));
return null;
}

if (null == versionGroup || versionGroup.NaN)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Error determining server version in DiscoverLocalExchangeServers(). The versionNumber property in AD has an invalid value of: " + versionGroup, " ", " ", " ")));
return null;
}

try
{
isFrontEnd = server.Get("serverRole");
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Encountered problem in DiscoverLocalExchangeServers() when accessing the 'serverRole' attribute in AD.\n", HResultToString(err.number), err.description)));
return null;
}

if (null == isFrontEnd ||isFrontEnd.NaN || (0 != isFrontEnd &amp;&amp; 1 != isFrontEnd))
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
INSTANCE_OMISSION_ID,
EVENT_TYPE_ERROR,
EventText(INSTANCE_OMISSION_MSG, new Array(fqdn, "Cannot determine server role in DiscoverLocalExchangeServers(). The serverRole property in AD returned an invalid value of: " + isFrontEnd, " ", " ", " ")));
return null;
}

if (versionGroup &gt;= 6944 &amp;&amp; versionGroup &lt; 9000)
{
if (1 == isFrontEnd)
versionGroup = "Exchange 2003 Frontend";
else
versionGroup = "Exchange 2003";
}
else
{
//server is not an Exchange 2003 server
return null;
}

try
{
distinguishedName = server.Get("distinguishedName");
adPathname = new ActiveXObject("Pathname");
adPathname.Set(distinguishedName, 4); // ADS_SETTYPE_DN
adPathname.EscapedMode = 4; // ADS_ESCAPEDMODE_OFF_EX

//For this given exchange server DN:
//"CN=NameOfServer,CN=Servers,CN=AdminGroupName,CN=Administrative Groups,CN=OrgName,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DomainName,DC=com"

//The following grabs element 2 (CN=AdminGroupName) and substring starting at position 3 (AdminGroupName)
adminGroup = adPathname.GetElement(2).substring(3);
//The following grabs element 4 (CN=OrgName) and substring starting at position 3 (OrgName)
org = adPathname.GetElement(4).substring(3);
}
catch(err)
{
//ignore error - these are not required attribute
}

try
{
routingGroupDN = server.Get("msExchHomeRoutingGroup");
adPathname = new ActiveXObject("Pathname");
adPathname.Set(routingGroupDN, 4); // ADS_SETTYPE_DN
adPathname.EscapedMode = 4; // ADS_ESCAPEDMODE_OFF_EX
//For this given routing group dn: CN=RGName,CN=Routing Groups,CN=First Administrative Group,CN=Administrative Groups,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=DomainName,DC=com
//The following grabs the routing group dn's element 0 (CN=RGName) and substring starting at position 3 (RGName)
routingGroup = adPathname.GetElement(0).substring(3);
}
catch(err)
{
/*ignore error - this is not a required attribute*/
}

try
{
version = server.Get("serialNumber"); //serialNumber seems to have more version info than versionNumber
}
catch(err)
{
/*ignore error - this is not a required attribute*/
}

}
else
{
return null;
}

try
{
//Only get mailbox count for Exchange 2000 or 2003 backends
if ("Exchange 2000" == versionGroup || "Exchange 2003" == versionGroup)
{
mailboxes = MailboxesPerServer(distinguishedName);
}
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_WARNING,
EventText(UNEXPECTED_ERROR_MSG, new Array("Encountered problem when calling MailboxesPerServer()", HResultToString(err.number), err.description)));
}

try
{
adSystemInfo = new ActiveXObject("ADSystemInfo");
adSite = adSystemInfo.SiteName;
}
catch(err)
{
// FIXME : CREATEEVENT
CreateEvent(
EVENT_SOURCE,
UNEXPECTED_ERROR_ID,
EVENT_TYPE_WARNING,
EventText(UNEXPECTED_ERROR_MSG, new Array("Problem accessing the ADSystemInfo object in function DiscoverLocalExchangeServer()", HResultToString(err.number), err.description)));
}

return new property(fullname, name, version, org, adminGroup, routingGroup, isFrontEnd, versionGroup, mailboxes, adSite, distinguishedName);

}

function MailboxesPerServer(serverDn)
{
var oConnect, command, objRootDSE, strCommand, sgRecordSet, mdbRecordSet, sgDn, mdbDn;
var mdbMailboxes, totalMailboxes;

if (null == serverDn)
throw new Error(160, "MailboxesPerServer(): Bad Argument: serverDn is null");//160 == ERROR_BAD_ARGUMENTS

objRootDSE = GetObject("LDAP://rootDSE");

oConnect = new ActiveXObject("ADODB.Connection");
oConnect.Provider = "ADsDSOObject";
oConnect.Open();

command = new ActiveXObject("ADODB.Command");
command.ActiveConnection = oConnect;
command.Properties("Page Size") = 1000;
command.Properties("Timeout") = 10;
command.Properties("searchscope") = 2;
command.Properties("Chase referrals") = 0x20 | 0x40;
command.Properties("Cache Results") = false;

totalMailboxes = 0;

serverDn = serverDn.replace(new RegExp("'","g"),"''"); //replace all ' with '' since ADSI treat ' as a special char
strCommand = "SELECT distinguishedName FROM 'LDAP://" + serverDn + "' WHERE " +
" objectCategory='msExchStorageGroup' AND NOT msExchRestore=TRUE " +
" OR objectCategory='msExchStorageGroup' AND NOT msExchRestore='*' ";
command.CommandText = strCommand;
sgRecordSet = command.Execute();

while (!sgRecordSet.EOF)
{
sgDn = sgRecordSet.Fields("distinguishedName").Value;
sgDn = sgDn.replace(new RegExp("'","g"), "''"); //replace all ' with '' since ADSI treat ' as a special char
strCommand = "SELECT name, distinguishedName FROM 'LDAP://" + sgDn + "' WHERE objectCategory='msExchPrivateMDB'";
command.CommandText = strCommand;
mdbRecordSet = command.Execute();
while (!mdbRecordSet.EOF)
{
mdbDn = mdbRecordSet.Fields("distinguishedName").Value;
mdbMailboxes = MailboxesPerMDB(mdbDn);
if (null != mdbMailboxes)
totalMailboxes += mdbMailboxes;
else
return null;
mdbRecordSet.MoveNext();
}

sgRecordSet.MoveNext();
}

return totalMailboxes;

function MailboxesPerMDB(mdbDn)
{
var mailboxes = 0;
var mailboxesReturnedFromQuery = 0;
var mailboxList = null;
var isLastQuery = false;
var start = 0;
var limit = 999;
var rs;

if (null == mdbDn)
throw new Error(160, "MailboxesPerMDB(): Bad Arguments: mdbDn is null");//160 == ERROR_BAD_ARGUMENTS

mdbDn = mdbDn.replace(new RegExp("'","g"), "''"); //replace all ' with '' since ADSI treat ' as a special char

//For example: if homeMDBBL contains 2400 mailboxes - then the data in AD is distributed as follow:
//range=0-999
//range=1000-1999
//range=2000-*
//
//The logic below would be:
//try query range=0-999. Return more than 0 mailboxes -&gt; Add count to the total and continue...
//now try query range=1000-1999. Return more than 0 mailboxes -&gt; Add count to the total and continue...
//now try query range=2000-2999. Returned 0 mailboxes. Mark this as the last query
//query range=2000-*. Add count to the total and terminate loop.

while(true)
{
mailboxesReturnedFromQuery = 0;

if (!isLastQuery)
strCommand = "SELECT 'homeMDBBL;range=" + start + "-" + limit + "' FROM 'LDAP://" + mdbDn + "'";
else
strCommand = "SELECT 'homeMDBBL;range=" + start + "-*' FROM 'LDAP://" + mdbDn + "'";

command.CommandText = strCommand;
rs = command.Execute();

if (!rs.EOF)
{
mailboxList = rs.Fields(0).Value;
if (null != mailboxList)
{
mailboxesReturnedFromQuery = mailboxList.toArray().length;
mailboxes += mailboxesReturnedFromQuery;
}
}

if (!isLastQuery)
{
if (mailboxesReturnedFromQuery &gt; 0)
{
start = limit + 1;
limit = start + 999;
}
else //range=start-limit query returned 0 mailboxes, this indicates we've reached the last query
{
isLastQuery = true;
}
}
else //(isLastQuery==true) i.e. finished running the last query, terminate loop
{
break;
}

}

return mailboxes;
}

}

MainRoutine:
{
var discoveryData, server, oExchangeServerRoleInstance, exchangeServerInstance;
var computerCollection, computerInstance;

// FIXME:: Ask Peter or Steve for creating an nt log event

CreateEvent(EVENT_SOURCE, START_SERVICE_DISCOVERY_ID, EVENT_TYPE_INFORMATION, START_SERVICE_DISCOVERY_MSG);

// FIXME: Check how to get this information
// if (ScriptContext.IsTargetAgentless)
// break MainRoutine;

discoveryData = oAPI.CreateDiscoveryData(SourceType, SourceId, ManagedEntityId);
server = DiscoverLocalExchangeServers();

if (null != server)
{
// Create Server (Exchange &amp; Exchange Frontend) collection with the
// Computer (full netbios name: domain\servername) as scope
oExchangeServerRoleInstance = discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']$");

oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", TargetComputer);
if (0 == server.isFrontEnd){
if (null != server.mailboxes){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/NumMailboxes$", server.mailboxes);
}
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/IsFrontEnd$", "False");
}else{
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/IsFrontEnd$", "True");
}
if(null !=server.fullname)
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/DisplayName$", server.fullname);
if (null != server.version){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/Version$", server.version);
}
if (null != server.adminGroup){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/AdminGroup$", server.adminGroup);
}
if (null != server.org){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/Organization$", server.org);
}
if (null != server.routingGroup){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/RoutingGroup$", server.routingGroup);
}
if (null != server.adSite){
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/ADSite$", server.adSite);
}
if(null != server.name)
{
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/Name$", server.name.toUpperCase());
}
if(null != server.name)
{
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/DistinguishedName$", server.name.toUpperCase());
}
if(null != server.versionGroup)
{
oExchangeServerRoleInstance.AddProperty("$MPElement[Name='Microsoft.Exchange.ServerRole.2003']/VersionGroup$", server.versionGroup);
}

discoveryData.AddInstance(oExchangeServerRoleInstance);
}

oAPI.Return(discoveryData);
CreateEvent(EVENT_SOURCE, FINISHED_SERVICE_DISCOVERY_ID, EVENT_TYPE_INFORMATION, FINISHED_SERVICE_DISCOVERY_MSG);

}//MainRoutine
</Script></Contents>
</File>
</Files>
</DataSource>
</Discovery>