Microsoft.Exchange.2010.CrossPremisesMailflowMonitoring.DiscoveryDS (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityInternal
RunAsDefault
OutputTypeSystem.Discovery.Data

Member Modules:

ID Module Type TypeId RunAs 
DS DataSource System.CommandExecuterDiscoveryDataSource Default

Overrideable Parameters:

IDParameterTypeSelector
IntervalSecondsint$Config/IntervalSeconds$
VerboseLoggingbool$Config/VerboseLogging$

Source Code:

<DataSourceModuleType ID="Microsoft.Exchange.2010.CrossPremisesMailflowMonitoring.DiscoveryDS" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="IntervalSeconds" type="xsd:integer"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="VerboseLogging" type="xsd:boolean"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int"/>
<OverrideableParameter ID="VerboseLogging" Selector="$Config/VerboseLogging$" ParameterType="bool"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.CommandExecuterDiscoveryDataSource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<ApplicationName>%windir%\System32\cscript.exe</ApplicationName>
<WorkingDirectory/>
<CommandLine>//Nologo $file/MicrosoftExchangeCrossPremiseMailflowMonitoringDiscovery.js$ 0 $MPElement$ $Target/Id$ $Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/PrincipalName$ "$Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/NetbiosComputerName$" "$Target/Host/Property[Type='Windows!Microsoft.Windows.Computer']/ActiveDirectorySite$" "$Target/Property[Type='Microsoft.Exchange.2010.MailboxRole']/IsVirtualServer$" "$Config/VerboseLogging$"</CommandLine>
<TimeoutSeconds>900</TimeoutSeconds>
<RequireOutput>true</RequireOutput>
<Files>
<File>
<Name>MicrosoftExchangeCrossPremiseMailflowMonitoringDiscovery.js</Name>
<Contents><Script>
// ----------------------------------------------------------------------
// Script to discover CrossPremiseMailflowMonitoring entities.
// ----------------------------------------------------------------------

var EXPECTED_ARGUMENT_COUNT = 8;
var UNEXPECTED_ARGUMENT_COUNT_ERROR_ID = 101;

var DISCOVERY_STARTED_INF_ID = 1470;
var DISCOVERY_ENDED_INF_ID = 1471;
var DISCOVERY_PROGRESS_INF_ID = 1472;

var CONNECT_AD_ERROR_ID = 104;
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 EVENT_SOURCE = "MicrosoftExchangeCrossPremiseMailflowMonitoringDiscovery.js";
var EVENT_TYPE_ERROR = 1;
var EVENT_TYPE_WARNING = 2;
var EVENT_TYPE_INFORMATION = 4;

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

var argumentsStr = "";
for (var i = 0; i &lt; WScript.Arguments.length; i++)
{
argumentsStr = argumentsStr.concat("\"", WScript.Arguments(i), "\" ");
}

if (WScript.Arguments.Unnamed.Count != EXPECTED_ARGUMENT_COUNT)
{
oAPI.LogScriptEvent(
EVENT_SOURCE,
UNEXPECTED_ARGUMENT_COUNT_ERROR_ID,
EVENT_TYPE_ERROR,
"Expected " + EXPECTED_ARGUMENT_COUNT + " arguments. But there were " + WScript.Arguments.Unnamed.Count + " arguments. Exiting script.\n Arguments: " + argumentsStr);

WScript.Quit(-1);
}

var sourceType = WScript.Arguments(0);
var sourceId = WScript.Arguments(1);
var managedEntityId = WScript.Arguments(2);
var computerPrincipalName = WScript.Arguments(3);
var computerNetbiosName = WScript.Arguments(4);
var computerActiveDirectorySite = WScript.Arguments(5);
var isVirtualServerString = WScript.Arguments(6); // For MailboxRole, this should always have value of either "true" or "false"
var verboseLoggingString = WScript.Arguments(7);

// Convert cluster related variables from string to bool.
var isVirtualServer = (isVirtualServerString.toLowerCase() == "true") ? true : false;
var verboseLogging = (verboseLoggingString.toLowerCase() == "true") ? true : false;

var infoOutput = "CrossPremiseMailflowMonitoring Discovery script \n"
+ " Message: ";

main();

function main()
{
LogEvent(DISCOVERY_STARTED_INF_ID, EVENT_TYPE_INFORMATION, infoOutput + "Discovery Script started.\n Arguments: " + argumentsStr);

var discoveryData = oAPI.CreateDiscoveryData(sourceType, sourceId, managedEntityId);

// Construct the MailboxRole class's Name key property.
var mailboxRoleName = computerNetbiosName + " (Mailbox) - " + computerActiveDirectorySite;

// Construct the CommonRole class's Name key property.
var commonRoleName = computerNetbiosName + " (Common) - " + computerActiveDirectorySite;

// ----------------------------------------------------------------------
// Instantiate CommonComponent classes hosted by all MailboxRole types.
// ----------------------------------------------------------------------

// Create the Mailbox.CrossPremisesMailflowMonitoring instance.
var isSiteCrossPremises = false;
try
{
isSiteCrossPremises = IsSiteCrossPremises(computerActiveDirectorySite);
}
catch (err)
{
oAPI.LogScriptEvent(
EVENT_SOURCE,
CONNECT_AD_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(CONNECT_AD_ERROR_MSG, new Array("Encountered problem when calling IsSiteCrossPremises()", HResultToString(err.number), err.description)));
}

if (isSiteCrossPremises)
{
var oMbxCrossPremisesMailflowMonitoring = discoveryData.CreateClassInstance("$MPElement[Name='Microsoft.Exchange.2010.Mailbox.CrossPremisesMailflowMonitoring']$");
oMbxCrossPremisesMailflowMonitoring.AddProperty("$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$", computerPrincipalName);
oMbxCrossPremisesMailflowMonitoring.AddProperty("$MPElement[Name='Microsoft.Exchange.2010.ServerRole']/RoleName$", mailboxRoleName);
oMbxCrossPremisesMailflowMonitoring.AddProperty("$MPElement[Name='Microsoft.Exchange.2010.Component']/ComponentName$", "Cross Premises Mailflow Monitoring - " + mailboxRoleName);
discoveryData.AddInstance(oMbxCrossPremisesMailflowMonitoring);
}

oAPI.Return(discoveryData);

LogEvent(DISCOVERY_ENDED_INF_ID, EVENT_TYPE_INFORMATION, infoOutput + "Exiting Discovery." );
}


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


// EventText - Replace escaped character %# with elements in the input array "param"
function EventText(eventText, param)
{
var index;
for (index in param) {
eventText = eventText.replace("%" + index, param[index]);
}

return eventText;
}


/////////// CROSS PREMISE SITE SELECTION START ///////////

// Get the default naming context.
function GetDC()
{
var root = GetObject("LDAP://rootDSE");
var dc = root.Get("defaultNamingContext");

return dc;
}


// Query AD to get the objects satisfying the query rules.
function ForEach(query, properties)
{
var connection = new ActiveXObject("ADODB.Connection");
connection.Open("Provider=ADsDSOObject;");

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

command.CommandText = "&lt;LDAP://CN=Configuration," + GetDC() + "&gt;;(" + query + ");AdsPath,CN;SubTree";

command.Properties("Cache Results") = false;
command.Properties("Page Size") = 1000;
command.Properties("Sort On") = "CN";
command.Properties("Timeout") = 120;

for (recordSet=command.Execute(); !recordSet.EOF; recordSet.MoveNext())
{
var path = recordSet.Fields("AdsPath").Value;
var object = GetObject(path);

if (object != null)
{
var result = properties(object);
}
if (result != null)
{
break;
}
}

connection.Close();
}


// Get the site of the current mailbox server.
function GetMailboxServerSites()
{
var dict = new Array();
ForEach("objectClass=msExchExchangeServer", function(object)
{
if (object.msExchServerSite != null)
{
dict[object.distinguishedName] = object.msExchServerSite;
}
});

return dict;
}


// Get the string array of the stringObject.
function GetStringArray(object)
{
if (object == null)
{
return new Array();
}
else if (typeof(object) == "string")
{
return new Array(object);
}
else
{
return object.toArray();
}
}


// Get the site that the connector belongs to.
function GetConnectorSite(object, siteDict)
{
var mtaPfxLength = "CN=Microsoft MTA,".length;

if (siteDict == null ||
object == null ||
object.homeMTA == null ||
object.homeMTA.length &lt;= mtaPfxLength)
{
return null;
}

var serverDN = object.homeMTA.substr(mtaPfxLength);
return siteDict[serverDN];
}


// Get the SendConnector's name, paths and site.
function ParseSendConnector(object, siteDict)
{
var site = GetConnectorSite(object, siteDict);
if (site == null)
{
return null;
}

var routePrefix = "smtp:";
var routes = GetStringArray(object.routingList);
var result = new Array();

for (i in routes)
{
if (routes[i].substr(0,5).toLowerCase() == routePrefix)
{
var idx = routes[i].indexOf(";");
if (idx &gt; 5)
{
var routeSuffix = routes[i].substr(5, idx-5);
var cost = routes[i].substr(idx+1);

if (routeSuffix.substr(0,1) == "*")
{
routeSuffix = routeSuffix.substr(1);
}

if (parseInt(cost) != NaN)
{
if (result["paths"] == null)
{
result["name"] = object.CN;
result["site"] = site;
result["paths"] = new Array();
}
var path = new Array();
path["route"] = routeSuffix;
path["cost"] = cost;
var len = result["paths"].length;
result["paths"][len] = path;
}
}
}
}

if (result["paths"] == null)
{
return null;
}

return result;
}


// Get the enabled SendConnectors.
function GetEnabledSendConnectors()
{
var siteDict = GetMailboxServerSites();
var connectors = new Array();
var idx = 0;

ForEach("objectClass=msExchRoutingSMTPConnector", function(object)
{
var connector = ParseSendConnector(object, siteDict);
if (connector != null &amp;&amp;
(object.msExchSmtpSendEnabled == null || object.msExchSmtpSendEnabled))
{
connectors[idx] = connector;
idx++;
}
});

return connectors;
}


// Verify if string 'suffix' is the suffix of 'str'
function IsSuffix(str, suffix)
{
var index = str.length - suffix.length;
return index &gt;= 0 &amp;&amp; str.substr(index).toUpperCase() == suffix.toUpperCase();
}


// Verify if string 'prefix' is the prefix of 'str'
function IsPrefix(str, prefix)
{
return str.length &gt;= prefix.length &amp;&amp;
str.substr(0, prefix.length).toUpperCase() == prefix.toUpperCase();
}


// If the send connector is in the site
function IsConnectorInSite(connector, site)
{
if (connector == null || site == null)
{
return false;
}

return IsPrefix(connector["site"], "CN=" + site);
}


// Get the best matched SendConnector for a domain.
function GetBestMatch(domain, connectors, site) //route, cost, site
{
if (domain == null || connectors == null)
{
return null;
}
currentPath = null;
currentConnector = null;

for (k in connectors)
{
var paths = connectors[k]["paths"];
for (i in paths)
{
if (IsSuffix(domain, paths[i]["route"]))
{
if (currentPath == null || currentPath["route"].length &lt; paths[i]["route"].length)
{
currentConnector = connectors[k];
currentPath = paths[i];
}
else if(currentPath["route"].length == paths[i]["route"].length)
{
if (IsConnectorInSite(connectors[k], site) ||
(!IsConnectorInSite(currentConnector, site) &amp;&amp; currentPath["cost"] &gt; paths[i]["cost"]))
{
currentConnector = connectors[k];
currentPath = paths[i];
}
}
}
}
}

return currentConnector;
}


// Check if a specific set of bits of an integer are set.
function BitsAllSet(integer, bits)
{
return (integer &amp; bits) == bits;
}


// Verify if the current site is a cross premises one.
function IsSiteCrossPremises(site)
{
var connectors = GetEnabledSendConnectors();
var result = false;
var TrustedMailOutboundEnabledBit = 0x1;
var bits = TrustedMailOutboundEnabledBit;

ForEach("objectClass=msExchDomainContentConfig", function(object)
{
if (BitsAllSet(object.msExchDomainContentConfigFlags, bits))
{
var connector = GetBestMatch(object.DomainName, connectors, site);
if (connector != null &amp;&amp; IsConnectorInSite(connector, site))
{
result = true;
return;
}
}
});

return result;
}

//
// Log to EventLog if verboseLogging is set
//
function LogEvent(eventId, eventType, message)
{
if (verboseLogging)
{
oAPI.LogScriptEvent(EVENT_SOURCE, eventId, eventType, message);
}
}

//////////// CROSS PREMISE SITE SELECTION END ////////////
</Script></Contents>
</File>
</Files>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.Discovery.Data</OutputType>
</DataSourceModuleType>