Microsoft_Exchange_2010_Execute_Diagnostic_Cmdlet (DataSourceModuleType)

Element properties:

TypeDataSourceModuleType
IsolationAny
AccessibilityPublic
RunAsSystem.PrivilegedMonitoringAccount
OutputTypeSystem.PropertyBagData

Member Modules:

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

Overrideable Parameters:

IDParameterTypeSelector
IntervalSecondsint$Config/IntervalSeconds$
SyncTimestring$Config/SyncTime$
TimeoutSecondsint$Config/TimeoutSeconds$
targetServerstring$Config/targetServer$
cmdletCommandstring$Config/cmdletCommand$
monitoringDataSourcestring$Config/monitoringDataSource$

Source Code:

<DataSourceModuleType ID="Microsoft_Exchange_2010_Execute_Diagnostic_Cmdlet" Accessibility="Public" RunAs="System!System.PrivilegedMonitoringAccount">
<Configuration>
<xsd:element name="IntervalSeconds" type="xsd:int"/>
<xsd:element name="SyncTime" type="xsd:string"/>
<xsd:element name="TimeoutSeconds" type="xsd:int"/>
<xsd:element name="targetServer" type="xsd:string"/>
<xsd:element name="cmdletCommand" type="xsd:string"/>
<xsd:element name="monitoringDataSource" type="xsd:string"/>
<xsd:element name="returnPerfDataForReports" type="xsd:string"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" ParameterType="int" Selector="$Config/IntervalSeconds$"/>
<OverrideableParameter ID="SyncTime" ParameterType="string" Selector="$Config/SyncTime$"/>
<OverrideableParameter ID="TimeoutSeconds" ParameterType="int" Selector="$Config/TimeoutSeconds$"/>
<OverrideableParameter ID="targetServer" ParameterType="string" Selector="$Config/targetServer$"/>
<OverrideableParameter ID="cmdletCommand" ParameterType="string" Selector="$Config/cmdletCommand$"/>
<OverrideableParameter ID="monitoringDataSource" ParameterType="string" Selector="$Config/monitoringDataSource$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedScript.PropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<ScriptName>Exchange_Execute_Diagnostic_Task.js</ScriptName>
<Arguments>"$Config/targetServer$" "$Config/cmdletCommand$" "$Config/monitoringDataSource$"</Arguments>
<ScriptBody><Script>

//*************************************************************
// $ScriptName: "Microsoft Exchange 2010 - Execute Diagnostic Cmdlet" $
//
// Execute an Exchange diagnostic cmdlet and insert the returned monitoring
// data into the Operations Manager database.
//
//*************************************************************

// Events

var DEFAULT_EVENT_SOURCE = "MSExchange Monitoring"; // To be used only if mandatory parameters are not specified, or when attempting to start the monitoring service
var MISSING_MANDATORY_PARAM_ID = 300;
var MISSING_MANDATORY_PARAM_MSG = "Cannot execute Exchange diagnostic cmdlet. The mandatory script parameter on position %0 is empty.";
var ATTEMPT_TO_START_MON_SVC_ID = 301;
var ATTEMPT_TO_START_MON_SVC_MSG = "Attempt %0 of %1 to start the MSExchangeMonitoring service.";
var ATTEMPT_TO_START_MON_SVC_RESULT_ID = 302;
var ATTEMPT_TO_START_MON_SVC_RESULT_MSG = "Attempt to start the MSExchangeMonitoring service using Win32_Service.StartService returned %0.";
var CANNOT_START_MON_SVC_ID = 303;
var MON_SVC_DISABLED_MSG = "The MSExchangeMonitoring service is disabled.";
var WMI_CANNOT_GET_MON_SVC_MSG = "WMI failed to get the MSExchangeMonitoring service object. Error: %0\n\n%1";
var MON_SVC_PROBABLY_NOT_INSTALLED_EXTRA_MSG = "This error typically indicates that the service is not installed.";
var NEXT_START_MON_SVC_DELAYED_MSG = "Previous attempts to start the MSExchangeMonitoring service failed. Monitoring is going to wait at least %0 minutes before trying again. " +
"If the problem preventing the service to start is fixed and the service is manually started the script will start to run the cmdlets immediately.";

// The source of the events below is going to be the string passed in the monitoringDataSource parameter
//
var SUCCESSFUL_EXECUTION_ID = 400;
var SUCCESSFUL_EXECUTION_MSG = "Exchange diagnostic cmdlet invocation succeeded.";
var NO_EVENTS_FROM_CMDLET_ID = 401;
var NO_EVENTS_FROM_CMDLET_MSG = "The command did not return any monitoring event.";
var DIAG_CMDLET_CONTROLLER_ERROR_ID = 402;
var DIAG_CMDLET_CONTROLLER_ERROR_MSG = "The diagnostic cmdlet controller failed to execute the command.\n\nError: %0\n\n%1";
var COM_OBJ_CREATION_ERROR_ID = 403;
var COM_OBJ_CREATION_ERROR_MSG = "The creation of the COM object used to execute the diagnostic cmdlet failed, possible installation problem.\n\nError: %0";

// Important error codes returned when trying to run a cmdlet
//
var EPT_S_NOT_REGISTERED = -2147416359; // 0x800106D9 - typically means service not running (it can be stopped, disabled, not installed, etc)
var RPC_E_CANTCALLOUT_INEXTERNALCALL = -2147418107; // 0x80010005 - RPC denied access to the end point
var RPC_S_CALL_FAILED_DNE = -2147416385; // 0x800106BF - RPC call failed but the end point was reachable at a certain point in time
var RPC_S_CALL_FAILED = -2147416386; // 0x800106BE - generic RPC call failed
var RPC_S_INVALID_BOUND = -2147416378; // 0x800106C6 - RPC the array bounds are invalid
var RPC_S_SERVER_TOO_BUSY = -2147416389; // 0x800106BB - The RPC server is too busy to complete this operation.
var CTL_E_ILLEGALFUNCTIONCALL = -2146828283; // 0x800A0005 - Invalid request

var WMI_HRESULT_FAILED_GETOBJECT = -2147217406; // 0x80041002

// Extra error information that is used to complement the event logged when the cmdlet command fails
//
var RPC_E_CANTCALLOUT_INEXTERNALCALL_EXTRA_MSG = "The script is not running as LocalSystem. The MSExchangeMonitoring service only accepts requests from LocalSystem.";
var RPC_S_CALL_FAILED_DNE_EXTRA_MSG = "This error typically indicates that the MSExchangeMonitoring service was stopped while processing the command.";
var RPC_S_INVALID_BOUND_EXTRA_MSG = "The command returned more events or performance counters values than allowed.";
var RPC_S_SERVER_TOO_BUSY_EXTRA_MSG = "The MSExchangeMonitoring service has too many outstanding cmdlets being executed.";
var CTL_E_ILLEGALFUNCTIONCALL_EXTRA_MSG = "The MSExchangeMonitoring service do not support scripts and only a limited set of Exchange cmdlets (test-*) and parameters (positional parameters are not allowed). The accepted syntax is also more restricted than the one accepted by the Exchange Management Shell.";

// Strings to control failures to start the Monitoring service
//
var lastSvcStartFailureTimeRegEntry = "HKLM\\SOFTWARE\\Microsoft\\Microsoft Operations Manager\\3.0\\Modules\\" + WScript.ScriptName + "\\LastServiceStartFailureTime";

// Minimum time without attempts to start the monitoring service, after a consecutive failures
//
var MINUTES_UNTIL_NEXT_START_ATTEMPT = 240;


// Typed property bag constants
var ALERT_DATA_TYPE = 0;
var EVENT_DATA_TYPE = 1;
var PERF_DATA_TYPE = 2;
var STATE_DATA_TYPE = 3;

// Global variable pointing to the OpsMgr07 ScriptAPI
//
var oAPI = new ActiveXObject("MOM.ScriptAPI");




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


// Global variable used to identify the target computer - it must be set with the FQDN of the target computer,
// this information must be the first parameter of the script
//
var _globalTargetComputer = WScript.Arguments(0);


function LoggingComputer()
{
return _globalTargetComputer;
}
























// Global variable used by the CreateEventEx to report the exact diagnostic cmdlet used by the rule, if one was specified
//
var _globalCmdletCommandScriptParam = null;

// Truncates a message, if necessary, appending the appropriate suffix
//
function TruncatedMsg(msg, maxMsgLength, truncatedMsgSuffix, defaultMsgSuffix)
{
if ((msg.length + defaultMsgSuffix.length) &gt; maxMsgLength)
{
msg = msg.substring(0, maxMsgLength - (truncatedMsgSuffix.length)) + truncatedMsgSuffix;
}
else
{
msg = msg + defaultMsgSuffix;
}

return msg;
}

function CreateEvent(strSource, lngEventID, lngEventType, strMsg, strComputer)
{
CreateEventEx(strSource, lngEventID, lngEventType, strMsg, "", strComputer, true);
}

function CreateEvent(strSource, lngEventID, lngEventType, strMsg, strInstanceName, strComputer)
{
CreateEventEx(strSource, lngEventID, lngEventType, strMsg, strInstanceName, strComputer, true);
}

function CreateReportEvent(strSource, lngEventID, lngEventType, strMsg, strComputer)
{
CreateEventEx(strSource, lngEventID, lngEventType, strMsg, "", strComputer, false);
}

function CreateEventEx(strSource, lngEventID, lngEventType, strMsg, strInstanceName, strComputer, blnIncRuleName)
{
var objNewEvent = oAPI.CreateTypedPropertyBag(EVENT_DATA_TYPE);

// For OpsMgr 2007 R2, the limit can be higher; but for SP1 it is around 128K for some monitors.
// We could have lifted the limit altogether but this runs the risk that a task may be logging too
// much data and causing the monitor to fail. For this reason, having a higher limit as opposed
// to none is safer -- as we would rather have the message get truncated then to risk the monitor failing.
// This higher limit should be adequate for including verbose and call stacks in the event message.
var MAX_MOM_MSG_LEN = 128000;

var truncatedMsgSuffix = "...";
var defaultMsgSuffix = "";


if (blnIncRuleName)
{
if (_globalCmdletCommandScriptParam != null)
defaultMsgSuffix += "\n\nDiagnostic command: \"" + _globalCmdletCommandScriptParam + "\"";
truncatedMsgSuffix += defaultMsgSuffix;
}
objNewEvent.AddValue("Message", TruncatedMsg(strMsg, MAX_MOM_MSG_LEN, truncatedMsgSuffix, defaultMsgSuffix));
objNewEvent.AddValue("EventNumber", lngEventID);
objNewEvent.AddValue("EventType", lngEventType);
objNewEvent.AddValue("EventSource", strSource);

if (strInstanceName == null)
{
strInstanceName = "";
}
objNewEvent.AddValue("EventInstanceName", strInstanceName);

if (strComputer == "" || strComputer == null)
{
strComputer = LoggingComputer();
}
objNewEvent.AddValue("LoggingComputer", strComputer);

oAPI.AddItem(objNewEvent);
}


function CreatePerformanceData (strObjectName, strCounterName, strInstanceName, dblSampleValue, strSrcComputer)
{
var objPerfData = oAPI.CreateTypedPropertyBag(PERF_DATA_TYPE);

objPerfData.AddValue("ObjectName", strObjectName);
objPerfData.AddValue("CounterName", strCounterName);
objPerfData.AddValue("InstanceName", strInstanceName);
objPerfData.AddValue("Value", dblSampleValue);

if (strSrcComputer == "" || strSrcComputer == null)
{
strSrcComputer = LoggingComputer();
}
objPerfData.AddValue("LoggingComputer", strSrcComputer);

oAPI.AddItem(objPerfData);
}


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


//////////////////////////////////////
// This function trims leading and trailing
// white spaces in a string
function Trim(string)
{

if (string == null)
return null;

//trim leading white space
string = string.replace( /^\s+/g, "" );

//trim trailing white space
string = string.replace( /\s+$/g, "" );

return string;
}


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



var NO_REGENTRY_SENTINEL = "...";

function GetRegEntry(strRegEntry)
{
var strEntryValue = "";
var objShell = new ActiveXObject("WScript.Shell");
var strEntryValue = NO_REGENTRY_SENTINEL;
var ERROR_FILE_NOT_FOUND = -2147024894; //ERROR_FILE_NOT_FOUND = 0x00000002

try {
strEntryValue = objShell.RegRead(strRegEntry);
} catch(err) {
if (err.number != ERROR_FILE_NOT_FOUND)
throw err;
strEntryValue = NO_REGENTRY_SENTINEL;
}
// Deals with the case when the value was created but not touched, in this case RegRead will return the registry entry
if (typeof(strEntryValue) == "string")
if (strRegEntry.toLowerCase() == strEntryValue.toLowerCase())
strEntryValue = NO_REGENTRY_SENTINEL;

return (strEntryValue);
}

function SetRegEntry(strRegEntry, value)
{
var objShell = new ActiveXObject("WScript.Shell");
objShell.RegWrite(strRegEntry, value);
}



// Gets a parameter that is mandatory for the script, if the parameter is empty (or not specified) creates the
// appropriate event to report the problem. The parameter is always trimmed before being returned
// to the caller. It returns null if the parameter is missing or empty.
//
function GetMandatoryScriptParameter(parameterPosition)
{
var parameterValue = null;
try
{
parameterValue = Trim(WScript.Arguments(parameterPosition));
}
catch(err) { }

if (parameterValue == null || parameterValue.length == 0)
{
CreateEvent(
DEFAULT_EVENT_SOURCE,
MISSING_MANDATORY_PARAM_ID,
EVENT_TYPE_ERROR,
EventText(MISSING_MANDATORY_PARAM_MSG, new Array(parameterPosition)),
"");
parameterValue = null;
}

return parameterValue;
}

// Function that checks if the MSExchangeMonitoring service is ready to be started. There are some
// circunstances that do not allow the service to be started (service not installed, service disabled, ...)
//
function IsMonitoringServiceReadyToBeStarted(monitoringDataSource)
{
var isReady = true; // Assume that the service is ready
var svcObj;

try
{
svcObj = GetObject("winmgmts://./root/cimv2:Win32_Service.Name='MSExchangeMonitoring'");
}
catch(err)
{
var extraErrorInfo = "";

if (err.number == WMI_HRESULT_FAILED_GETOBJECT)
{
extraErrorInfo = MON_SVC_PROBABLY_NOT_INSTALLED_EXTRA_MSG;
}

CreateEvent(
DEFAULT_EVENT_SOURCE,
CANNOT_START_MON_SVC_ID,
EVENT_TYPE_ERROR,
EventText(WMI_CANNOT_GET_MON_SVC_MSG, new Array(HResultToString(err.number) + " - " + err.description, extraErrorInfo)),
"");

isReady = false;
}

// Only check the other requirements if the previous check passed
//
if (isReady)
{
if (svcObj.StartMode == "Disabled")
{
// Service cannot be started because it is disabled
//
CreateEvent(
DEFAULT_EVENT_SOURCE,
CANNOT_START_MON_SVC_ID,
EVENT_TYPE_ERROR,
MON_SVC_DISABLED_MSG,
"");
isReady = false;
}
}

if (isReady)
{
// An attempt to start the service should be made only if the last failure to start it happened some time ago
//
var timeLastAttemptFailure = GetRegEntry(lastSvcStartFailureTimeRegEntry);
// If the registry entry is not set it means that there is no record of a previous failure, so the monitoring service should be considered
// ready to be started, otherwise it is necessary to check when the last failure to start it happened.
//
if (NO_REGENTRY_SENTINEL != timeLastAttemptFailure)
{
timeLastAttemptFailure = new Date(timeLastAttemptFailure);
var now = new Date();
var minutesAfterLastAttempt = (now - timeLastAttemptFailure) / 60000; // The result of the subtraction is in milliseconds, divide to get a number in minutes
if (minutesAfterLastAttempt &lt; MINUTES_UNTIL_NEXT_START_ATTEMPT)
{
var waitInMinutes = Math.round(MINUTES_UNTIL_NEXT_START_ATTEMPT - minutesAfterLastAttempt);
if (waitInMinutes &lt; 1)
waitInMinutes = 1;
isReady = false;
CreateEvent(
monitoringDataSource,
DIAG_CMDLET_CONTROLLER_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(NEXT_START_MON_SVC_DELAYED_MSG, new Array(waitInMinutes.toString())),
"");
}
else
{
// Set the registry entry to the not set sentinel so a new interval can be started in case of new failure
//
SetRegEntry(lastSvcStartFailureTimeRegEntry, NO_REGENTRY_SENTINEL);
}
}
}

return isReady;
}

// Checks if the script is running as local system
//
function IsRunningAsSystem()
{
var retval = false;

var WshNetwork = new ActiveXObject("WScript.Network");

// Use the well-known SID of the system account ("S-1-5-18") to get the correspondent object

var 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 comparison below since, if the account is
// system, the name is extracted from the same location for both objects

if (WshNetwork.UserName == WMISystemAcct.AccountName)
retval = true;

return(retval);
}


// Function that attempts to start the MSExchangeMonitoring service, it does not guarantee that the
// service is going to be running after its call.
//
function AttemptToStartMonitoringService()
{
var defaultWaitMSec = 8000;
var svcObj = GetObject("winmgmts://./root/cimv2:Win32_Service.Name='MSExchangeMonitoring'");


// Wait a random amount of time so scripts running at the same time do not try to start the
// service all at once.
//
WScript.Sleep(1000 + Math.round(defaultWaitMSec * Math.random()))

// MSExchangeMonitoring does not support pause, so its possible states are:
// "Running", "Stopped", "Start Pending", "Stop Pending", and "Unknown".
// Check the pending states first
//
if (svcObj.State.lastIndexOf("Pending") != -1)
{
// Give some time to the service so it can complete the state transition
//
WScript.Sleep(defaultWaitMSec);
}

// Check if during the wait the service was not started before attempting to start it
//
if (svcObj.State != "Running")
{
// Some of the possible return codes from StartService, check the documentation of
// Win32_Service.StartService for a complete list of possible return codes.
//
var successCode = 0;
var serviceAlreadyRunningCode = 10;

var returnCode = svcObj.StartService();
// Just report return code if it was not expected.
if ((returnCode != successCode) &amp;&amp; (returnCode != serviceAlreadyRunningCode))
{
CreateEvent(
DEFAULT_EVENT_SOURCE,
ATTEMPT_TO_START_MON_SVC_RESULT_ID,
EVENT_TYPE_INFORMATION, // This is not necessarily an error, report the return code just to help debug (if necessary)
EventText(ATTEMPT_TO_START_MON_SVC_RESULT_MSG, new Array(returnCode.toString())),
"");
}
WScript.Sleep(defaultWaitMSec);
}
}

function main()
{
// TODO: add usage information, parameter order etc ...

// Get the mandatory parameters
_globalCmdletCommandScriptParam = GetMandatoryScriptParameter(1); // Mapped from cmdletCommand on OpsMgr data source
var monitoringDataSource = GetMandatoryScriptParameter(2); // Mapped from monitoringDataSource on OpsMgr data source

// Check if all mandory parameters were specified
if ((_globalCmdletCommandScriptParam == null) || (monitoringDataSource == null))
{
// No need to create event reporting the problem since GetMandatoryScriptParameter
// already created one for each missing parameter, just bail.
return;
}

// Get the optional parameters
var returnPerfDataForReports = null;
try
{
returnPerfDataForReports = Trim(WScript.Arguments(3)); // Mapped from returnPerfDataForReports on OpsMgr data source
} catch(err) { }
if (returnPerfDataForReports == null)
returnPerfDataForReports = "true";

// Create the COM object that allows to execute the diagnostic cmdlet
//
try
{
var diagnosticCmdletController = new ActiveXObject("DiagnosticCmdletController");
}
catch (err)
{
CreateEvent(
monitoringDataSource,
COM_OBJ_CREATION_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(COM_OBJ_CREATION_ERROR_MSG, new Array(HResultToString(err.number) + " - " + err.description)),
"");
return;
}

// Variables to control the loop that tries to run the diagnostic cmdlet
//
var maxAttemptsToStartMonitoringService = 3;
var totalAttemptsToStartMonitoringService = 0;
var notRun = true;

//
// The maximum amount of time to sleep before execution of cmdlet.
// This will add deeper granularity together with "CmdletSyncTime" property (Bug 228540).
//
// The "19 seconds" value is based on the following limitation, assuming that SCOM fires test-cmdlets sequentially:
// 10 (test-task calls) * 19 (maximum sleep time) + 10 (test-task calls) * 10 (average maximum duration of execution) &lt; 300 seconds (the interval with which tasks run repeatedly).
//
// There are 10 different test-task calls:
// ----------------------------------
// 1. Test-ActiveSyncConnectivity
// 2. Test-EcpConnectivity (Internal)
// 3. Test-EcpConnectivity (External)
// 4. Test-ImapConnectivity
// 5. Test-OutlookConnectivity (AutoDiscover)
// 6. Test-OutlookConnectivity (Enterprise AutoDiscover)
// 7. Test-OwaConnectivity (Internal)
// 8. Test-OwaConnectivity (External)
// 9. Test-PopConnectivity
// 10. Test-WebServicesConnectivity
//
var maxCmdletSleepTime = 19000; // 19 seconds.

// Sleep random amount of time within a range of [0; 19) seconds before actual execution of cmdlet.
WScript.Sleep(Math.round(maxCmdletSleepTime * Math.random()));

do
{
try
{
diagnosticCmdletController.Run(_globalCmdletCommandScriptParam, monitoringDataSource);
notRun = false;
}
catch (err)
{
// Check if the last attempt to start the service was already executed.
//
if (totalAttemptsToStartMonitoringService == maxAttemptsToStartMonitoringService)
{
// Last attempt to start the service on this run of the script failed. Set a registry entry to indicate the time of it,
// this is going to be used to control when the next runs of the script should try again.
//
var timeLastAttemptFailure = new Date();
SetRegEntry(lastSvcStartFailureTimeRegEntry, timeLastAttemptFailure.toUTCString());

// The appropriate event and message is going to be generated below (see case for EPT_S_NOT_REGISTERED).
//
}

if ((err.number == EPT_S_NOT_REGISTERED) &amp;&amp; (totalAttemptsToStartMonitoringService &lt; maxAttemptsToStartMonitoringService))
{
if (!IsMonitoringServiceReadyToBeStarted(monitoringDataSource))
{
// The appropriate events were generated on the function above, here just return
//
return;
}
else
{
totalAttemptsToStartMonitoringService++;

CreateEvent(
DEFAULT_EVENT_SOURCE,
ATTEMPT_TO_START_MON_SVC_ID,
EVENT_TYPE_INFORMATION,
EventText(ATTEMPT_TO_START_MON_SVC_MSG, new Array(totalAttemptsToStartMonitoringService, maxAttemptsToStartMonitoringService)),
"");

AttemptToStartMonitoringService();
}
}
else
{
var extraErrorInfo = "";

switch (err.number)
{
case RPC_E_CANTCALLOUT_INEXTERNALCALL:
if (!IsRunningAsSystem())
extraErrorInfo = RPC_E_CANTCALLOUT_INEXTERNALCALL_EXTRA_MSG;
break;
case RPC_S_CALL_FAILED_DNE:
case RPC_S_CALL_FAILED:
extraErrorInfo = RPC_S_CALL_FAILED_DNE_EXTRA_MSG;
break;
case RPC_S_INVALID_BOUND:
extraErrorInfo = RPC_S_INVALID_BOUND_EXTRA_MSG;
break;
case RPC_S_SERVER_TOO_BUSY:
extraErrorInfo = RPC_S_SERVER_TOO_BUSY_EXTRA_MSG;
break;
case CTL_E_ILLEGALFUNCTIONCALL:
extraErrorInfo = CTL_E_ILLEGALFUNCTIONCALL_EXTRA_MSG;
break;
case EPT_S_NOT_REGISTERED:
extraErrorInfo = EventText(NEXT_START_MON_SVC_DELAYED_MSG, new Array(MINUTES_UNTIL_NEXT_START_ATTEMPT.toString()));
break;
}

CreateEvent(
monitoringDataSource,
DIAG_CMDLET_CONTROLLER_ERROR_ID,
EVENT_TYPE_ERROR,
EventText(DIAG_CMDLET_CONTROLLER_ERROR_MSG, new Array(HResultToString(err.number) + " - " + err.description, extraErrorInfo)),
"");

return;
}
}
}while (notRun);

// Check if performace data should be submitted and if so submit it
if (returnPerfDataForReports.toLowerCase() != "false")
{
var tmpPerfVBArray = new VBArray(diagnosticCmdletController.PerformanceCounters);
var perfCounters = tmpPerfVBArray.toArray();
for (i in perfCounters)
{
CreatePerformanceData(
monitoringDataSource, // Use the monitoring data source as the object
perfCounters[i].Counter,
perfCounters[i].Instance,
perfCounters[i].Value,
"");
}
}

// Submit monitoring events
var tmpEventVBArray = new VBArray(diagnosticCmdletController.Events);
var events = tmpEventVBArray.toArray();
for (i in events)
{
CreateEvent(
monitoringDataSource, // Use the monitoring data source as the event source
events[i].Identifier,
events[i].Type,
events[i].Message,
events[i].InstanceName,
"");
}

// The diagnostic cmdlet should have returned at least one monitoring event, if not report this as an error.
if (events.length == 0)
{
CreateEvent(
monitoringDataSource,
NO_EVENTS_FROM_CMDLET_ID,
EVENT_TYPE_ERROR,
NO_EVENTS_FROM_CMDLET_MSG,
"");
}
else
{
// If the code got to this point it means that the cmdlet was successfully executed and it returned
// some monitoring events, report the success to resolve any possible alert.
CreateEvent(
monitoringDataSource,
SUCCESSFUL_EXECUTION_ID,
EVENT_TYPE_SUCCESS,
SUCCESSFUL_EXECUTION_MSG,
"");
}
}

main();
oAPI.ReturnItems();

</Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</DataSource>
</MemberModules>
<Composition>
<Node ID="DS"/>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>