<DataSourceModuleType ID="Microsoft_Exchange_2010_Execute_Database_Space_Troubleshooter" Accessibility="Internal" 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="ScriptName" type="xsd:string"/>
<xsd:element name="Arguments" type="xsd:string"/>
<xsd:element name="ScriptBody" type="xsd:string"/>
<xsd:element name="MonitoringDataSource" type="xsd:string"/>
<xsd:element name="MaxStartDelaySeconds" type="xsd:int"/>
</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="Arguments" ParameterType="string" Selector="$Config/Arguments$"/>
<OverrideableParameter ID="MonitoringDataSource" ParameterType="string" Selector="$Config/MonitoringDataSource$"/>
<OverrideableParameter ID="MaxStartDelaySeconds" ParameterType="int" Selector="$Config/MaxStartDelaySeconds$"/>
</OverrideableParameters>
<ModuleImplementation>
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="Microsoft.Exchange.2010.TimedDatabaseSpaceTroubleshooterScript.PropertyBagProvider">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime>$Config/SyncTime$</SyncTime>
<!-- Diagnostic script common library -->
<CommonLibraryScriptName>DiagnosticScriptCommonLibrary.ps1</CommonLibraryScriptName>
<CommonLibraryScriptBody>
# Copyright (c) 2010 Microsoft Corporation. All rights reserved.
#
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK
# OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#
# This script is a library of functions for common diagnostic script executions.
# Diagnostic scripts need to dot source this file to invoke the functions.
# Writes the collection of monitoring events to the pipeline.
#
function Write-MonitoringEvents
{
Write-Output $script:monitoringEvents;
}
</CommonLibraryScriptBody>
<!-- Wrapper script to execute the diagnostic script -->
<ExecutionScriptName>ExecuteDiagnosticScript.ps1</ExecutionScriptName>
<ExecutionArguments>-MonitoringDataSource '$Config/MonitoringDataSource$' -MaxStartDelaySeconds '$Config/MaxStartDelaySeconds$'</ExecutionArguments>
<ExecutionScriptBody>
# Copyright (c) 2010 Microsoft Corporation. All rights reserved.
#
# THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE RISK
# OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
#
# Executes a diagnostic PowerShell script and output results as typed property bags that
# can be mapped to SCOM monitoring events in the management pack to drive states of monitors.
#
# Usage:
# .\ExecuteDiagnosticScript.ps1 -MonitoringDataSource <event data source> [-MaxStartDelaySeconds <max. seconds to sleep before executing diagnostic PS script>] -DiagnosticScriptName <diagnostic PS script name to execute> [-DiagnosticScriptArguments <arguments into diagnostic PS script>]
#
# Examples:
# .\ExecuteDiagnosticScript.ps1 -MonitoringDataSource 'MSExchange Monitoring TestSampleHealth' -MaxStartDelaySeconds 15 -DiagnosticScriptName '.\TestSampleHealth.ps1' -DiagnosticScriptArguments '-VerboseLogging:$true'
param(
# Monitoring event data source.
[string] $MonitoringDataSource = $(throw "MonitoringDataSource must be specified."),
# Max. seconds to sleep before executing diagnostic PS script.
[UInt16] $MaxStartDelaySeconds,
# Name of the diagnostic script to execute.
[string] $DiagnosticScriptName = $(throw "DiagnosticScriptName must be specified."),
# Arguments to the diagnostic script as string.
[string] $DiagnosticScriptArguments
)
# Dot source the common library.
. ".\DiagnosticScriptCommonLibrary.ps1";
# Event IDs and messages for logging execution results.
$SUCCESSFUL_EXECUTION_ID = 400;
$SUCCESSFUL_EXECUTION_MSG = "Exchange diagnostic PowerShell script invocation succeeded.";
$NO_EVENTS_FROM_SCRIPT_ID = 401;
$NO_EVENTS_FROM_SCRIPT_MSG = "The diagnostic PowerShell script did not return any monitoring event.";
$SCRIPT_EXECUTION_ERROR_ID = 402;
# Creates an event property bag that can be mapped to a monitoring event in the MP.
#
function Create-Event (
[string] $source,
[int] $id,
[int] $type,
[string] $message,
[string] $instanceName,
[string] $computer)
{
$event = $api.CreateTypedPropertyBag(1); # 1 = Event Data.
# Truncates a message if necessary, and appending the appropriate suffix.
#
function Truncate-Message (
[string] $message)
{
# For OpsMgr 2007 R2, the limit can be higher; but for SP1 it is around 128K for some monitors.
$MaxOpsMgrMessageLength = 128000;
# Main entry function.
#
function Main
{
# Adding random sleep if specified.
#
if ($MaxStartDelaySeconds -gt 0)
{
if ($MaxStartDelaySeconds -lt [UInt16]::MaxValue)
{
# Add one to include the max value in the randomly generated value.
$MaxStartDelaySeconds++;
}
$r = New-Object System.Random;
Start-Sleep -Seconds $r.Next($MaxStartDelaySeconds);
}
# Execute the diagnostic script.
#
$results = $null;
$results = Invoke-Expression "& '$DiagnosticScriptName' $DiagnosticScriptArguments";
trap
{
Write-Log "Diagnostic script failed with the following error: $($Error[0])";
# Diagnostic scripts must return a collection of valid event objects.
#
if (($results -eq $null) -or ($eventCount -eq 0))
{
Write-Log "No monitoring events returned from diagnostic script.";
# For PS V1, we need to add MOM snapin from the wrapper script even though
# [Microsoft.EnterpriseManagement.Configuration.HealthState] does not get
# referenced until being used by TestGenericRollupHealth.ps1.
#
$momSnapinName = "Microsoft.EnterpriseManagement.OperationsManager.Client";
$momSnapin = Get-PSSnapin -Name $momSnapinName -ErrorAction SilentlyContinue;
if ($momSnapin -eq $null)
{
# Attempt to add the MOM snapin but don't fail if it cannot be added.
# When executing scripts on a machine where the SCOM console is not installed,
# it is expected that the snapin won't be added.
Add-PSSnapin -Name $momSnapinName -ErrorAction SilentlyContinue;
$momSnapin = Get-PSSnapin -Name $momSnapinName -ErrorAction SilentlyContinue;
if ($momSnapin -eq $null)
{
Write-Log "The '$($momSnapinName)' snap-in was not added: $($Error[0])";
}
}
# Create the OpsMgr Scripting API object.
$api = New-Object -ComObject "MOM.ScriptAPI";
Main;
# Return event property bags to OpsMgr.
$api.ReturnItems();