Exchange 2007 ESE DB and Disk Discovery

Microsoft.Exchange2007.Component.Ese.Database.Disk.Discovery.DS (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsMicrosoft.Exchange2007.Account.ViewOnly
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource Microsoft.Windows.TimedScript.DiscoveryProvider Default

Overrideable Parameters:

IDParameterTypeSelectorDisplay NameDescription
IntervalSecondsint$Config/IntervalSeconds$Interval SecondsInterval Seconds
SyncTimestring$Config/SyncTime$Sync TimeSync Time
TimeoutSecondsint$Config/TimeoutSeconds$Timeout SecondsTimeout Seconds

Source Code:

<DataSourceModuleType ID="Microsoft.Exchange2007.Component.Ese.Database.Disk.Discovery.DS" Accessibility="Internal" RunAs="ExLibrary!Microsoft.Exchange2007.Account.ViewOnly" Batching="false">
<Configuration>
<xsd:element minOccurs="1" name="ClassId" type="xsd:string"/>
<xsd:element minOccurs="1" name="RoleName" type="xsd:string"/>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element minOccurs="0" name="SyncTime" type="xsd:string"/>
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="SyncTime" Selector="$Config/SyncTime$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.DiscoveryProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>DiscoverEseMdbDisk.wsf</ScriptName>
<Arguments>$MPElement$ $Target/Id$ $Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/PrincipalName$ $Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/NetbiosComputerName$ $Config/ClassId$ "$Config/RoleName$"</Arguments>
<ScriptBody><Script>
&lt;?xml version="1.0" ?&gt;
&lt;package&gt;
&lt;job id="main"&gt;
&lt;script language="VBScript"&gt;
Function GetVolumeDisks()
SET wmiLocator = CreateObject("WbemScripting.SWbemLocator")
SET wmiServer = wmiLocator.ConnectServer(null, "root/cimv2")
SET volumeDisks = wmiServer.ExecQuery("SELECT DeviceID, Name FROM Win32_Volume WHERE DriveType = 3")

DIM vbDisks()
REDIM vbDisks(volumeDisks.Count-1)

DIM index
index = 0

FOR EACH disk IN volumeDisks
IF NOT IsNull(disk.Name) AND NOT IsEmpty(disk.Name) THEN
vbDisks(index) = disk.Name
index = index + 1
END IF
NEXT

GetVolumeDisks = vbDisks
END FUNCTION
&lt;/script&gt;
&lt;script language="JScript"&gt;
var EXPECTED_ARGUMENT_COUNT = 6;
var UNEXPECTED_ARGUMENT_COUNT_ERROR_ID = 101;
var CONNECT_AD_ERROR_ID = 204;
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 CONNECT_AD_ERROR_MSG_TEXT = "Encountered problem when calling LDAP for Storage Groups";
var REGKEY_NOT_FOUND = -2147024894;
var REGKEY_NOT_FOUND_ERROR_ID = 107;
var REGKEY_NOT_FOUND_ERROR_MSG = "Error getting value from registry. Error: %0\n" + "Error number: %1" + "\n" + "Error description: %2";
var REGKEY_CLUSTER = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Exchange\\Cluster\\";
var REGKEY_DBREP = "SOFTWARE\\Microsoft\\Exchange\\Replay\\State";
var REGKEY_QUEUE = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Exchange\\v8.0\\Setup\\MsiInstallPath";
var TABLE_NOT_FOUND = -2147467259; // might need for msExchStandbyCopyMachines in some cases;
var RECORDSET_ERROR_ID = 206;
var RECORDSET_ERROR_MSG = "LDAP retrieved more than one record. Using the first found as default for ";
var DISK_PATH_ERROR_ID = 207;
var DISK_PATH_ERROR_MSG = "Disk drive not found for path ";

var EVENT_TYPE_ERROR = 1;
var EVENT_TYPE_WARNING = 2;
var EVENT_TYPE_INFORMATION = 4;

var oAPI = new ActiveXObject("Mom.ScriptAPI");

if (WScript.Arguments.Unnamed.Count != EXPECTED_ARGUMENT_COUNT)
{
oAPI.LogScriptEvent(
"DiscoverEseMdbDisk.js",
UNEXPECTED_ARGUMENT_COUNT_ERROR_ID,
EVENT_TYPE_ERROR,
"Expected " + EXPECTED_ARGUMENT_COUNT + " arguments. But there were " + WScript.Arguments.Unnamed.Count + " arguments. Exiting script.");
WScript.Quit(-1);
}

var sourceId = WScript.Arguments(0);
var managedEntityId = WScript.Arguments(1);
var computerPrincipalName = WScript.Arguments(2);
var NetbiosComputerName = WScript.Arguments(3);
var classID = WScript.Arguments(4);
var roleName = WScript.Arguments(5);

main();

function main()
{
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Edge']$")
{
CheckLdapPermission();
}

var discoveryData = oAPI.CreateDiscoveryData(0, sourceId, managedEntityId);
var oContainment, oEseComponent;
var objItem;
var oRoleInstance = discoveryData.CreateClassInstance(classID);
oRoleInstance.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oRoleInstance.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole']/RoleName$", roleName);

// ----------------------------------------------------------------------
// Instantiate ESE from Transport, CcrNode, SccCluster, Standalone
// ----------------------------------------------------------------------
//
// Create the ESE instance.
if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Edge']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Hub']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.SccCluster']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Standalone']$" == classID)
{
oEseComponent = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Ese']$");
oEseComponent.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oEseComponent.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "ESE (" + computerPrincipalName + ")");
discoveryData.AddInstance(oEseComponent);
// ----------------------------------------------------------------------
// Create containment relationship containing ESE
// ----------------------------------------------------------------------
//
if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Edge']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Hub']$" == classID)
{
oContainment = discoveryData.CreateRelationshipInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Contains.Ese']$");
}
else if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$" == classID)
{
oContainment = discoveryData.CreateRelationshipInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode.Contains.Ese']$");
}
else
{
oContainment = discoveryData.CreateRelationshipInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Contains.Ese']$");
}
oContainment.Source = oRoleInstance;
oContainment.Target = oEseComponent;
discoveryData.AddInstance(oContainment);
}

var arrayVolumeDisk = null;
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.CcrCluster']$")
{
// check if mount point exists in this server before using mount point for iterative search on path
var wmiLocator = new ActiveXObject("WbemScripting.SWbemLocator");
var wmiServer = wmiLocator.ConnectServer(null, "root\\cimv2");
var mountPoints = wmiServer.ExecQuery("SELECT DeviceID FROM Win32_Volume WHERE DriveType = 3 AND DriveLetter = NULL");
if (mountPoints.Count != 0)
{
// create an array of all the disks including mount point
var vbDisks = GetVolumeDisks();
var disks = vbDisks.toArray();
arrayVolumeDisk = new Array();
for (var index in disks)
{
// disk value in same case used in performance counter
var diskValue = disks[index].substr(0, disks[index].length - 1);
// disk key in lower case for matching requirements
var diskKey = diskValue.toLowerCase();
arrayVolumeDisk[diskKey] = diskValue;
}
}
}

// ----------------------------------------------------------------------
// Discover &amp;amp; Instantiate Queue Disk from Transport
// ----------------------------------------------------------------------
//
// Read from queue file
if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Edge']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Transport.Hub']$" == classID)
{
var ForReading = 1;
var TristateUseDefault = -2;
var fso = new ActiveXObject("Scripting.FileSystemObject");
var regInstallPath = RegReader(REGKEY_QUEUE);
if (!regInstallPath)
{
// default path
regInstallPath = "C:\\Program Files\\Microsoft\\Exchange Server\\";
}
var queueConfigPath = regInstallPath + "\\Bin\\EdgeTransport.exe.config";
var queueDiskDrive;
if (!fso.FileExists(queueConfigPath)) // file not found
{
oAPI.Return(discoveryData);
return;
}

var textStream = fso.OpenTextFile(queueConfigPath, ForReading, TristateUseDefault);
var textLine;
var searchIndex;
var queueValuePath;
while (!textStream.AtEndOfStream)
{
textLine = textStream.ReadLine();
var searchIndex = textLine.search(/QueueDatabasePath/i);
if(searchIndex != -1)
{
queueValuePath = textLine.substr(textLine.indexOf("value"));
queueValuePath = queueValuePath.substring(queueValuePath.indexOf("\"") + 1, queueValuePath.lastIndexOf("\""));
}
}
textStream.Close();

if (!queueValuePath) // queue not found
{
oAPI.Return(discoveryData);
return;
}
// ----------------------------------------------------------------------
// Instantiate Queue Disk
// ----------------------------------------------------------------------
//
if (null == arrayVolumeDisk)
{
queueDiskDrive = queueValuePath.substr(0, 2);
}
else
{
queueDiskDrive = GetDriveFromPath(arrayVolumeDisk, queueValuePath);
}

if (queueDiskDrive != null)
{
// Create queue disk instance.
var oQueue = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk.Queue']$");
oQueue.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oQueue.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk']/DeviceID$", queueDiskDrive);
oQueue.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Queue Disk " + queueDiskDrive + " (" + computerPrincipalName + ")");
discoveryData.AddInstance(oQueue);
}
else
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", DISK_PATH_ERROR_ID, EVENT_TYPE_ERROR, DISK_PATH_ERROR_MSG + queueValuePath);
}

oAPI.Return(discoveryData);
return;
}

var NetbiosServer = NetbiosComputerName;
var LogShipping = false; // default no DB Replication
// ----------------------------------------------------------------------
// Prepare to Discover only MDB disks from CcrNode
// ----------------------------------------------------------------------
//
// Get CCR Cluster Server from registry for CCR NODE ONLY
if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$" == classID)
{
var objShell = new ActiveXObject("WScript.Shell");
var strRegEntry = REGKEY_CLUSTER + "ServerName_MSExchangeSA1";
NetbiosServer = RegReader(strRegEntry);

// DB Replication CCR case
LogShipping = true;
}

// ----------------------------------------------------------------------
// Discover MDB from CcrCluster, SccCluster, Standalone
// Discovery only disks for CcrNode (not instantiate MDB)
// ----------------------------------------------------------------------
//
if (NetbiosServer != null &amp;amp;&amp;amp;
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.SccCluster']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Standalone']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.CcrCluster']$" == classID)
{
// Discover MDB through LDAP
var ADS_SCOPE_SUBTREE = 2;
var objConnection = new ActiveXObject("ADODB.Connection");
var objCommand = new ActiveXObject("ADODB.Command");
// Open connection
objConnection.Provider = "ADsDSOObject";
objConnection.Open("Active Directory Provider");
objCommand.ActiveConnection = objConnection;
objCommand.Properties("Page Size") = 1000;
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE;
var rootDse = GetObject("LDAP://RootDSE");
var configurationNC = rootDse.Get("ConfigurationNamingContext");
var objRecordSet;

// use objectCategory instead of objectClass since its indexed
try
{
// Get admin group
objCommand.CommandText = "SELECT distinguishedName FROM 'LDAP://"
+ configurationNC + "' WHERE objectCategory='msExchAdminGroup' AND cn='*FYDIBOHF23SPDLT*'";
objRecordSet = objCommand.Execute;
if (objRecordSet.EOF)
{
oAPI.Return(discoveryData);
return;
}
objRecordSet.MoveFirst();
var adminGroup = objRecordSet.Fields("distinguishedName").Value;
// If we retrieved more than one record, we send a warning
objRecordSet.MoveNext();
if (!objRecordSet.EOF)
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", RECORDSET_ERROR_ID, EVENT_TYPE_WARNING, RECORDSET_ERROR_MSG + NetbiosComputerName);
}

// Get exchange container
objCommand.CommandText = "SELECT distinguishedName FROM 'LDAP://"
+ adminGroup + "' WHERE objectCategory='msExchServersContainer'";
objRecordSet = objCommand.Execute;
if (objRecordSet.EOF)
{
oAPI.Return(discoveryData);
return;
}
objRecordSet.MoveFirst();
var exContainer = objRecordSet.Fields("distinguishedName").Value;
// If we retrieved more than one record, we send a warning
objRecordSet.MoveNext();
if (!objRecordSet.EOF)
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", RECORDSET_ERROR_ID, EVENT_TYPE_WARNING, RECORDSET_ERROR_MSG + NetbiosComputerName);
}

// Get storageGroup
var localCopyAttribute = "";
if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Standalone']$" == classID)
{
localCopyAttribute = ", msExchHasLocalCopy";
}
objCommand.CommandText = "SELECT distinguishedName, name, msExchESEParamLogFilePath"
+ localCopyAttribute + ", msExchStandbyCopyMachines FROM 'LDAP://CN=" + NetbiosServer + ","
+ exContainer + "' WHERE objectCategory='msExchStorageGroup'";
objRecordSet = objCommand.Execute;
if (objRecordSet.EOF) // if there is no Exchange Storage Group found we exit
{
oAPI.Return(discoveryData);
return;
}
objRecordSet.MoveFirst();
}
catch (err)
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", CONNECT_AD_ERROR_ID, EVENT_TYPE_ERROR,
EventText(CONNECT_AD_ERROR_MSG, new Array(CONNECT_AD_ERROR_MSG_TEXT, HResultToString(err.number), err.description)));
oAPI.Return(discoveryData);
return;
}

var storageGroup, storageGroupName, LogFilePath, LogDiskDrive;
var mdbRecordSet, oMdb, oLog, oMDisk, Identity, EdbFilePath, EdbDiskDrive, MountAtStartup, oMdbName;
var arrayLogDisk = new Array();
var arrayDataDisk = new Array();
while (!objRecordSet.EOF) // iterate through all storage groups
{
storageGroup = objRecordSet.Fields("distinguishedName").Value;
storageGroupName = objRecordSet.Fields("name").Value;
LogFilePath = objRecordSet.Fields("msExchESEParamLogFilePath").Value;
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.CcrCluster']$")
{
if (false == LogShipping)
{
if (null != objRecordSet.Fields("msExchStandbyCopyMachines").Value)
{
LogShipping = true; // DB Replication SCR source case
}
else if ("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Standalone']$" == classID &amp;amp;&amp;amp;
1 == objRecordSet.Fields("msExchHasLocalCopy").Value)
{
LogShipping = true; // DB Replication LCR case
}
}
// ----------------------------------------------------------------------
// Prepare Mailbox Log Disks for later instantiation
// ----------------------------------------------------------------------
//
if (null == arrayVolumeDisk)
{
LogDiskDrive = LogFilePath.substr(0, 2);
}
else
{
LogDiskDrive = GetDriveFromPath(arrayVolumeDisk, LogFilePath);
}

if (LogDiskDrive != null)
{
arrayLogDisk[LogDiskDrive] = LogDiskDrive;
}
else
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", DISK_PATH_ERROR_ID, EVENT_TYPE_ERROR, DISK_PATH_ERROR_MSG + LogFilePath);
}
}
// ----------------------------------------------------------------------
// Get Private Mailbox DB and Disks
// ----------------------------------------------------------------------
//
objCommand.CommandText = "SELECT name, msExchEDBFile, msExchEDBOffline, homeMDBBL FROM 'LDAP://" + storageGroup + "' WHERE objectCategory='msExchPrivateMDB'";
mdbRecordSet = objCommand.Execute;
if (!mdbRecordSet.EOF)
{
mdbRecordSet.MoveFirst();
while(!mdbRecordSet.EOF) // iterate through all private MDB
{
EdbFilePath = mdbRecordSet.Fields("msExchEDBFile").Value;
// ----------------------------------------------------------------------
// Instantiate Private Mailbox DB
// ----------------------------------------------------------------------
//
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$")
{
oMdbName = mdbRecordSet.Fields("name").Value;
Identity = NetbiosServer + "\\" + storageGroupName + "\\" + oMdbName;
MountAtStartup = !mdbRecordSet.Fields("msExchEDBOffline").Value;
oMdb = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database.PrivateMdb']$");
oMdb.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/Identity$", Identity);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/EdbFilePath$", EdbFilePath);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/LogFilePath$", LogFilePath);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/MountAtStartup$", MountAtStartup);
oMdb.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Private MDB (" + Identity + ")");
discoveryData.AddInstance(oMdb);
// ----------------------------------------------------------------------
// Create containment relationship containing MDB
// ----------------------------------------------------------------------
//
oContainment = discoveryData.CreateRelationshipInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Contains.Database']$");
oContainment.Source = oRoleInstance;
oContainment.Target = oMdb;
discoveryData.AddInstance(oContainment);
}
// ----------------------------------------------------------------------
// Prepare Mailbox DB Disks for later instantiation
// ----------------------------------------------------------------------
//
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.CcrCluster']$")
{
if (null == arrayVolumeDisk)
{
EdbDiskDrive = EdbFilePath.substr(0, 2);
}
else
{
EdbDiskDrive = GetDriveFromPath(arrayVolumeDisk, EdbFilePath);
}

if (EdbDiskDrive != null)
{
arrayDataDisk[EdbDiskDrive] = EdbDiskDrive;
}
else
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", DISK_PATH_ERROR_ID, EVENT_TYPE_ERROR, DISK_PATH_ERROR_MSG + EdbFilePath);
}
}
mdbRecordSet.MoveNext();
} //end while(!mdbRecordSet.EOF)
} //end if (!mdbRecordSet.EOF)
// ----------------------------------------------------------------------
// Get Public Mailbox DB and Disks
// ----------------------------------------------------------------------
//
objCommand.CommandText = "SELECT name, msExchEDBFile, msExchEDBOffline FROM 'LDAP://" + storageGroup + "' WHERE objectCategory='msExchPublicMDB'";
mdbRecordSet = objCommand.Execute;
if (!mdbRecordSet.EOF)
{
mdbRecordSet.MoveFirst();
while (!mdbRecordSet.EOF) // iterate through all public folders
{
EdbFilePath = mdbRecordSet.Fields("msExchEDBFile").Value;
// ----------------------------------------------------------------------
// Instantiate Public Folder
// ----------------------------------------------------------------------
//
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$")
{
oMdbName = mdbRecordSet.Fields("name").Value;
Identity = NetbiosServer + "\\" + storageGroupName + "\\" + oMdbName;
MountAtStartup = !mdbRecordSet.Fields("msExchEDBOffline").Value;
oMdb = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database.PublicFolder']$");
oMdb.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/Identity$", Identity);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/EdbFilePath$", EdbFilePath);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/LogFilePath$", LogFilePath);
oMdb.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Database']/MountAtStartup$", MountAtStartup);
oMdb.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Public MDB (" + Identity + ")");
discoveryData.AddInstance(oMdb);
// ----------------------------------------------------------------------
// Create containment relationship containing MDB
// ----------------------------------------------------------------------
//
oContainment = discoveryData.CreateRelationshipInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Contains.Database']$");
oContainment.Source = oRoleInstance;
oContainment.Target = oMdb;
discoveryData.AddInstance(oContainment);
}
// ----------------------------------------------------------------------
// Prepare Mailbox DB Disks for later instantiation
// ----------------------------------------------------------------------
//
if (classID != "$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.CcrCluster']$")
{
if (null == arrayVolumeDisk)
{
EdbDiskDrive = EdbFilePath.substr(0, 2);
}
else
{
EdbDiskDrive = GetDriveFromPath(arrayVolumeDisk, EdbFilePath);
}

if (EdbDiskDrive != null)
{
arrayDataDisk[EdbDiskDrive] = EdbDiskDrive;
}
else
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", DISK_PATH_ERROR_ID, EVENT_TYPE_ERROR, DISK_PATH_ERROR_MSG + EdbFilePath);
}
}
mdbRecordSet.MoveNext();
} // end while(!mdbRecordSet.EOF)
} // end if (!mdbRecordSet.EOF)
objRecordSet.MoveNext();
} // end while(!objRecordSet.EOF)

// ----------------------------------------------------------------------
// Instantiate Log Disks
// ----------------------------------------------------------------------
//
for (LogDiskDrive in arrayLogDisk)
{
oLog = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk.MailboxLog']$");
oLog.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oLog.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk']/DeviceID$", LogDiskDrive);
oLog.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Log Disk " + LogDiskDrive + " (" + computerPrincipalName + ")");
discoveryData.AddInstance(oLog);
}

// ----------------------------------------------------------------------
// Instantiate Mailbox DB Disks
// ----------------------------------------------------------------------
//
for (EdbDiskDrive in arrayDataDisk)
{
oMDisk = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk.MailboxDB']$");
oMDisk.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oMDisk.AddProperty("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.Disk']/DeviceID$", EdbDiskDrive);
oMDisk.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "MDB Disk " + EdbDiskDrive + " (" + computerPrincipalName + ")");
discoveryData.AddInstance(oMDisk);
}
} // end if (classID...)

// check if it is DB Replication SCR target case
if (false == LogShipping &amp;amp;&amp;amp;
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.CcrNode']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.SccCluster']$" == classID ||
"$MPElement[Name='ExLibrary!Microsoft.Exchange2007.ServerRole.Mailbox.Standalone']$" == classID)
{
var scrTargetArray = GetScrTarget();
if (scrTargetArray != null &amp;amp;&amp;amp; scrTargetArray.length &amp;gt; 0)
{
LogShipping = true; // DB Replication SCR target case
}
}

// ----------------------------------------------------------------------
// Instantiate DB Replication
// ----------------------------------------------------------------------
//
if (LogShipping)
{
// Create Mailbox Log instance.
var oDbRep = discoveryData.CreateClassInstance("$MPElement[Name='ExLibrary!Microsoft.Exchange2007.Component.LogShipping']$");
oDbRep.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oDbRep.AddProperty("$MPElement[Name='System!System.Entity']/DisplayName$", "Log Shipping (" + computerPrincipalName + ")");
discoveryData.AddInstance(oDbRep);
}

oAPI.Return(discoveryData);
}

// CheckLdapPermission - Checks if the user the right permission to LDAP calls
function CheckLdapPermission()
{
var adStateOpen = 1; // Used for ADODB or LDAP on checking State of RecordSet or Connection

var connection = new ActiveXObject("ADODB.Connection");
var command = new ActiveXObject("ADODB.Command");
var recordSet;

// Open the Connection
connection.Provider = "ADsDSOObject";
connection.Open();
command.ActiveConnection = connection;

var rootDirectory = GetObject("LDAP://RootDSE");

if (null == rootDirectory)
{
WScript.Quit(-1);
}

var configurationContext = rootDirectory.Get("ConfigurationNamingContext");
command.CommandText = "&amp;lt;LDAP://" + configurationContext + "&amp;gt;;(objectCategory=msExchAdminGroupContainer);cn;subtree";
recordSet = command.Execute;

if (!recordSet.EOF)
{
// Have read permission with LDAP Query on Exchange Server
}
else
{
oAPI.LogScriptEvent("DiscoverEseMdbDisk.js", CONNECT_AD_ERROR_ID, EVENT_TYPE_ERROR, "CheckLdapPermission - Access Denied.");
WScript.Quit(-1);
}

// Clean Up.
if (recordSet.State == adStateOpen)
recordSet.Close;
if (connection.State == adStateOpen)
connection.Close;

recordSet = null;
command = null;
connection = null;
}

// Returns the drive from the given path
function GetDriveFromPath(disks, path)
{
if (null == disks || null == path)
{
// log information and exit
return;
}

// we need to convert this to lower case to preserve consistency with disks key/index
var drive = path.toLowerCase();

// we iterate from the longest possible drive path and downward until we hit the drive
while (disks[drive] == null)
{
var index = drive.lastIndexOf("\\");
drive = drive.substr(0, index);
}

return disks[drive];
}

// Returns an array of all servers in GUID which set this server as a target
function GetScrTarget()
{
var HKLM = 0x80000002;
var oLoc = new ActiveXObject("WbemScripting.SWbemLocator");
var oSvc = oLoc.ConnectServer(null, "root\\default");
var oReg = oSvc.Get("StdRegProv");
var oMethod = oReg.Methods_.Item("EnumKey");
var oInParam = oMethod.InParameters.SpawnInstance_();
oInParam.hDefKey = HKLM;
oInParam.sSubKeyName = REGKEY_DBREP;
var oOutParam = oReg.ExecMethod_(oMethod.Name, oInParam);

if (null == oOutParam || null == oOutParam.sNames)
{
return null;
}

return oOutParam.sNames.toArray();
}

// Returns the value in string obtained from the registry key
function RegReader(strRegEntry)
{
var objShell = new ActiveXObject("WScript.Shell");
var result;
try
{
result = objShell.RegRead(strRegEntry);
}
catch (err)
{
if (err.number != REGKEY_NOT_FOUND)
{
oAPI.LogScriptEvent(
"DiscoverEseMdbDisk.js",
REGKEY_NOT_FOUND_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(REGKEY_NOT_FOUND_ERROR_MSG, new Array("Encountered problem when calling RegRead", HResultToString(err.number), err.description)));
}
// RegKey not found, so we exit
return null;
}
if (typeof(result) == "string" &amp;amp;&amp;amp; strRegEntry.toLowerCase() == result.toLowerCase())
{
return null;
}
return result;
}

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

// 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;
}

&lt;/script&gt;
&lt;/job&gt;
&lt;/package&gt;
</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>