Monitoring Exchange 2010 Database Backup and Mount Status
The Exchange 2010 Management Pack for System Center Operations Manager 2007 / 2012 does some of its monitoring remotely rather than on the mailbox server itself. This means that various PowerShell scripts will run on a schedule from the RMS (OM 2007) or the All Management Servers Resource Pool (OM 2012). One of the recommendations in KB2592561 is to disable the database mount status monitor. Several years ago I developed a management pack to monitor whether a database is mounted or not, but in doing this I created a new class that is hosted by the actual database server rather than remotely. This effectively spreads out the load required for this monitoring and also creates a a new class that you can target for other custom monitoring.
Chris Maiden, a Premier Field Engineer out of Washington, DC, recently extended this management pack further by adding a check for LastFullBackup. To test out this management pack in your lab just make sure you already have the latest version of the Exchange 2010 management and import the attached MP.
**Update** (4/21/2014)
One of my peers, Volkan Coskun, found that the discovery script was filtering out valid DBs so I updated the script. We were filtering on Mastertype=server and on HA mailboxes Mastertype is set to databaseAvailabilityGroup. The script has been updated in the attached MP.
Monitors
- Exchange 2010 Agent Hosted Database Mounted
- This monitor runs every 5 minutes to determine if the discovered database is mounted or not
- Exchange 2010 Mailbox Monitoring LastFullBackup Check
- This monitor runs twice a day. The warning threshold is 7 days while the critical threshold is 14 days.
- DatabaseHostAvailabilityRollup Dependency Monitor
- This monitor rolls up health from the custom class to the mail Mailbox Database Service class in the Exchange 2010 MP
Views
- Exchange 2010 Mailboxes (Agent Hosted)
Health Explorer
Alerts
Management Pack
<ManagementPack ContentReadable="true" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<Manifest>
<Identity>
<ID>Custom.Example.Exchange.2010.MailboxMonitoring</ID>
<Version>1.0.0.0</Version>
</Identity>
<Name>Exchange 2010 Mailbox Monitoring</Name>
<References>
<Reference Alias="MicrosoftExchange2010">
<ID>Microsoft.Exchange.2010</ID>
<Version>14.3.38.4</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="SC">
<ID>Microsoft.SystemCenter.Library</ID>
<Version>6.1.7221.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="Windows">
<ID>Microsoft.Windows.Library</ID>
<Version>6.1.7221.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="Health">
<ID>System.Health.Library</ID>
<Version>6.1.7221.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
<Reference Alias="System">
<ID>System.Library</ID>
<Version>6.1.7221.0</Version>
<PublicKeyToken>31bf3856ad364e35</PublicKeyToken>
</Reference>
</References>
</Manifest>
<TypeDefinitions>
<EntityTypes>
<ClassTypes>
<ClassType ID="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" Accessibility="Public" Abstract="false" Base="MicrosoftExchange2010!Microsoft.Exchange.2010.Component" Hosted="true" Singleton="false">
<Property ID="DatabaseName" Type="string" Key="true" CaseSensitive="false" MinLength="0" Length="256" />
</ClassType>
</ClassTypes>
<RelationshipTypes>
<RelationshipType ID="Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.DatabaseServiceContainsDatabase" Accessibility="Public" Abstract="false" Base="System!System.Containment">
<Source>MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.DatabaseService</Source>
<Target>Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService</Target>
</RelationshipType>
<RelationshipType ID="Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.WindowsComputerHostsDatabaseService" Accessibility="Internal" Abstract="false" Base="System!System.Hosting">
<Source>Windows!Microsoft.Windows.Computer</Source>
<Target>Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService</Target>
</RelationshipType>
</RelationshipTypes>
</EntityTypes>
<ModuleTypes>
<DataSourceModuleType ID="Custom.Example.Exchange.2010.MailboxMonitoring.Datasource" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="Server" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
<OverrideableParameter ID="Server" Selector="$Config/Server$" ParameterType="string" />
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="SS" TypeID="System!System.Scheduler">
<Scheduler>
<SimpleReccuringSchedule>
<Interval>$Config/IntervalSeconds$</Interval>
<SyncTime />
</SimpleReccuringSchedule>
<ExcludeDates />
</Scheduler>
</DataSource>
<ProbeAction ID="PS" TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.Probe">
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<Server>$Config/Server$</Server>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="PS">
<Node ID="SS" />
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>
<DataSourceModuleType ID="Custom.Example.Exchange.2010.MailboxMonitoring.DS.MountedScriptCookdown" Accessibility="Internal" Batching="false">
<Configuration>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="MBServer" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="DatabaseName" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
<OverrideableParameter ID="MBServer" Selector="$Config/MBServer$" ParameterType="string" />
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<DataSource ID="DS" TypeID="System!System.SimpleScheduler">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<SyncTime />
</DataSource>
<ProbeAction ID="Probe" TypeID="Windows!Microsoft.Windows.PowerShellPropertyBagProbe">
<ScriptName>MailboxMon2.ps1</ScriptName>
<ScriptBody>#Get parameters
param($mbxsrv)
#initialize dbcount
$dbcount = 0
#creates the SCOM scripting API
$api = New-Object -comObject MOM.ScriptAPI
#debug event to verify cookdown
# $api.logscriptevent("MailboxMon2.PS1",9898,4,"Verifying cookdown, this event should only happen once per script iteration" )
# $api.logscriptevent("MailboxMon2.PS1",9899,4,$mbxsrv)
#Add Exchange Snap-in for Exchange PowerShell cmdlet support
Function Load-ExchangeSnapin
{
if (! (Get-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue) )
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}
}
Load-ExchangeSnapin
#get database information
$dbs = get-mailboxdatabase -server $mbxsrv -status | select name, server, mounted
#get public folder information
$pfs = get-publicfolderdatabase -server $mbxsrv -status | select name, server, mounted
#debug
$sDBStatus = "`nDatabase Status:`n"
#enddebug
#Loop through databases
foreach($db in $dbs)
{
#we found a database so increment dbcount
$dbcount = $dbcount + 1
#debug
$sDash = " - Mounted = ";
$sDBStatus = $sDBStatus + $db.Name + $sDash + $db.Mounted + "`n";
#enddebug
#add information to individual property bags
$bag = $api.CreatePropertyBag()
$bag.AddValue('DatabaseName', $db.Name)
$bag.AddValue('Mounted', $db.Mounted)
$bag
}
#Loop through public folders
foreach($pf in $pfs)
{
#we found a database so increment dbcount
$dbcount = $dbcount + 1
#debug
$sDash = " - Mounted = ";
$sDBStatus = $sDBStatus + $pf.Name + $sDash + $pf.Mounted + "`n";
#enddebug
#add information to individual property bags
$bag = $api.CreatePropertyBag()
$bag.AddValue('DatabaseName', $pf.Name)
$bag.AddValue('Mounted', $pf.Mounted)
$bag
}
#debug
#Write-Host "Test: MailboxMon2.PS1: " + $sDBStatus
#$api.logscriptevent("MailboxMon1.PS1",9899,4,$sDBStatus)
#enddebug
#Handle auto-activation scenario
if($dbcount -gt 0)
{
$mbserv = Get-MailboxServer $mbxsrv
if($mbserv.DatabaseCopyAutoActivationPolicy -eq "Blocked")
{
$api.logscriptevent("MailboxMon1.PS1",4369,1,"The Server is hosting active DBs but is auto-activation blocked")
}
}</ScriptBody>
<Parameters>
<Parameter>
<Name>mbxsrv</Name>
<Value>$Config/MBServer$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="Probe">
<Node ID="DS" />
</Node>
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
</DataSourceModuleType>
<ProbeActionModuleType ID="Custom.Example.Exchange.2010.MailboxMonitoring.Probe" Accessibility="Internal" Batching="false" PassThrough="false">
<Configuration>
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="Server" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
<OverrideableParameter ID="Server" Selector="$Config/Server$" ParameterType="string" />
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<ProbeAction ID="PS" TypeID="Windows!Microsoft.Windows.PowerShellPropertyBagProbe">
<ScriptName>Ex2010LastFullBackup.ps1</ScriptName>
<ScriptBody>param($Server)
$ScriptName = "Ex2010LastFullBackup.ps1"
Function Load-ExchangeSnapin
{
if (! (Get-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue) )
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}
}
Function Create-ErrorEvent ([string]$ScriptName, [string]$EventSeverity, [int]$EventID, [string]$EventDescription)
{
$api = new-object -comObject 'MOM.ScriptAPI'
$api.LogScriptEvent($ScriptName, $EventID, $EventSeverity, $EventDescription)
}
Load-ExchangeSnapin
$MBdbs = Get-Mailboxdatabase -server $Server -status
$PFdbs = Get-PublicFolderDatabase -server $Server -status
$Today = Get-Date
$api = new-object -comObject 'MOM.ScriptAPI'
ForEach ($db in $MBdbs)
{
$DisplayName = $db.AdminDisplayName
if($db.LastFullBackup -eq $null)
{
$Days = 99
}
else
{
$BckTime = $db.LastFullBackup
$Delta = $Today - $BckTime
$Days = $Delta.Days
}
$bag = $api.CreatePropertyBag()
$bag.AddValue('AdminDisplayName', $DisplayName)
$bag.AddValue('LastFullBackupDays',$Days)
$bag
$List += $DisplayName + " " + $Days + "`r`n"
}
ForEach ($db in $PFdbs)
{
$DisplayName = $db.AdminDisplayName
if($db.LastFullBackup -eq $null)
{
$Days = 99
}
else
{
$BckTime = $db.LastFullBackup
$Delta = $Today - $BckTime
$Days = $Delta.Days
}
$bag = $api.CreatePropertyBag()
$bag.AddValue('AdminDisplayName', $DisplayName)
$bag.AddValue('LastFullBackupDays',$Days)
$bag
$List += $DisplayName + " " + $Days + "`r`n"
}
</ScriptBody>
<Parameters>
<Parameter>
<Name>Server</Name>
<Value>$Config/Server$</Value>
</Parameter>
</Parameters>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</ProbeAction>
</MemberModules>
<Composition>
<Node ID="PS" />
</Composition>
</Composite>
</ModuleImplementation>
<OutputType>System!System.PropertyBagData</OutputType>
<InputType>System!System.BaseData</InputType>
</ProbeActionModuleType>
</ModuleTypes>
<MonitorTypes>
<UnitMonitorType ID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentHostedDBMountedMonitorType" Accessibility="Internal">
<MonitorTypeStates>
<MonitorTypeState ID="Mounted" NoDetection="false" />
<MonitorTypeState ID="NotMounted" NoDetection="false" />
</MonitorTypeStates>
<Configuration>
<xsd:element minOccurs="1" name="MBServer" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="DatabaseName" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
</OverrideableParameters>
<MonitorImplementation>
<MemberModules>
<DataSource ID="DS" TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.DS.MountedScriptCookdown">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<MBServer>$Config/MBServer$</MBServer>
<DatabaseName>$Config/DatabaseName$</DatabaseName>
</DataSource>
<ConditionDetection ID="CDHealthy" TypeID="System!System.ExpressionFilter">
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='DatabaseName']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Mounted']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">True</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</ConditionDetection>
<ConditionDetection ID="CDNotMounted" TypeID="System!System.ExpressionFilter">
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='DatabaseName']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='Mounted']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">False</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</ConditionDetection>
</MemberModules>
<RegularDetections>
<RegularDetection MonitorTypeStateID="Mounted">
<Node ID="CDHealthy">
<Node ID="DS" />
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="NotMounted">
<Node ID="CDNotMounted">
<Node ID="DS" />
</Node>
</RegularDetection>
</RegularDetections>
</MonitorImplementation>
</UnitMonitorType>
<UnitMonitorType ID="Custom.Example.Exchange.2010.MailboxMonitoring.LastFullBackupMonitorType" Accessibility="Internal">
<MonitorTypeStates>
<MonitorTypeState ID="Healthy" NoDetection="false" />
<MonitorTypeState ID="Warning" NoDetection="false" />
<MonitorTypeState ID="Critical" NoDetection="false" />
</MonitorTypeStates>
<Configuration>
<xsd:element minOccurs="1" name="IntervalSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="TimeoutSeconds" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="Server" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="WarningThresholdDays" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="CriticalThresholdDays" type="xsd:integer" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
<xsd:element minOccurs="1" name="DatabaseName" type="xsd:string" xmlns:xsd="https://www.w3.org/2001/XMLSchema" />
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="IntervalSeconds" Selector="$Config/IntervalSeconds$" ParameterType="int" />
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int" />
<OverrideableParameter ID="WarningThresholdDays" Selector="$Config/WarningThresholdDays$" ParameterType="int" />
<OverrideableParameter ID="CriticalThresholdDays" Selector="$Config/CriticalThresholdDays$" ParameterType="int" />
</OverrideableParameters>
<MonitorImplementation>
<MemberModules>
<DataSource ID="DS" TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.Datasource">
<IntervalSeconds>$Config/IntervalSeconds$</IntervalSeconds>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
<Server>$Config/Server$</Server>
</DataSource>
<ConditionDetection ID="HealthyCD" TypeID="System!System.ExpressionFilter">
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='AdminDisplayName']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='LastFullBackupDays']</XPathQuery>
</ValueExpression>
<Operator>Less</Operator>
<ValueExpression>
<Value Type="Double">$Config/WarningThresholdDays$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</ConditionDetection>
<ConditionDetection ID="WarningCD" TypeID="System!System.ExpressionFilter">
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='AdminDisplayName']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='LastFullBackupDays']</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Double">$Config/WarningThresholdDays$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='LastFullBackupDays']</XPathQuery>
</ValueExpression>
<Operator>Less</Operator>
<ValueExpression>
<Value Type="Double">$Config/CriticalThresholdDays$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</ConditionDetection>
<ConditionDetection ID="CriticalCD" TypeID="System!System.ExpressionFilter">
<Expression>
<And>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="String">Property[@Name='AdminDisplayName']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="String">$Config/DatabaseName$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Double">Property[@Name='LastFullBackupDays']</XPathQuery>
</ValueExpression>
<Operator>GreaterEqual</Operator>
<ValueExpression>
<Value Type="Double">$Config/CriticalThresholdDays$</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</And>
</Expression>
</ConditionDetection>
</MemberModules>
<RegularDetections>
<RegularDetection MonitorTypeStateID="Healthy">
<Node ID="HealthyCD">
<Node ID="DS" />
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="Warning">
<Node ID="WarningCD">
<Node ID="DS" />
</Node>
</RegularDetection>
<RegularDetection MonitorTypeStateID="Critical">
<Node ID="CriticalCD">
<Node ID="DS" />
</Node>
</RegularDetection>
</RegularDetections>
</MonitorImplementation>
</UnitMonitorType>
</MonitorTypes>
</TypeDefinitions>
<Monitoring>
<Discoveries>
<Discovery ID="Custom.Example.Exchange.2010.MailboxMonitoring.Discovery.DiscoverAgentHostedDBs" Enabled="true" Target="MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.MailboxMonitoring" ConfirmDelivery="true" Remotable="true" Priority="Normal">
<Category>Discovery</Category>
<DiscoveryTypes>
<DiscoveryClass TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" />
</DiscoveryTypes>
<DataSource ID="DS" TypeID="Windows!Microsoft.Windows.TimedPowerShell.DiscoveryProvider">
<IntervalSeconds>43200</IntervalSeconds>
<SyncTime />
<ScriptName>DiscoverDBs.ps1</ScriptName>
<ScriptBody>#Set variables
$computerPrincipalName = "$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$"
$computerNetbiosName = "$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetbiosComputerName$"
$sourceId = "$MPElement$"
$managedEntityId = "$Target/Id$"
$componentNameProperty = "$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Component']/ComponentName$"
$instanceNameProperty = "$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Component']/InstanceName$"
$displayNameProperty = "$MPElement[Name='System!System.Entity']/DisplayName$"
$principalNameProperty = "$MPElement[Name='Windows!Microsoft.Windows.Computer']/PrincipalName$"
$componentName = "Mounted Database (Hosted by Agent)"
$dnsDomainNameProperty = "$Target/Host/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/ForestDnsName$"
#$api.logscriptevent("DiscoverDBs.ps1",9898,4,"Start DiscoverDBs.ps1.")
#creates the SCOM scripting API
$api = New-Object -comObject MOM.ScriptAPI
#Create Discovery Data
$discoveryData = $api.CreateDiscoveryData(0, $sourceId, $managedEntityId)
#Add Exchange Snap-in for Exchange PowerShell cmdlet support
Function Load-ExchangeSnapin
{
if (! (Get-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction:SilentlyContinue) )
{
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
}
}
Load-ExchangeSnapin
#Get databases on local server that are currently mounted
$mailboxDBs = @(Get-MailboxDatabase -Server $computerPrincipalName -Status | where {($_.recovery -eq $false)})
#Get public folders on local server that are currently mounted
$publicFolderDBs = @(Get-PublicFolderDatabase -Server $computerPrincipalName -Status | where {($_.recovery -eq $false)})
#debug
$sDiscoveredItems = "`nDiscovered Databases:`n"
#enddebug
#Loop through each database
$mailboxDBs | foreach {
#We discovered a database, now create an instance
$db = $discoveryData.CreateClassInstance("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService']$");
#Populate the properties of the class and key properties of hosting classes
$db.AddProperty($componentNameProperty, $componentName);
$db.AddProperty($instanceNameProperty, $_.Name);
$db.AddProperty($displayNameProperty, $_.Name);
$db.AddProperty($principalNameProperty, $computerPrincipalName);
$db.AddProperty("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService']/DatabaseName$", $_.Name);
#Add instance back to workflow
$discoveryData.AddInstance($db);
#Create an instance of the DatabaseService class so we can link the two with a relationship
$dbName = $_.Name
$dbService = $discoveryData.CreateClassInstance("$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.DatabaseService']$");
$dbService.AddProperty("$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Service']/ServiceName$", "Mailbox Database Service - $dbName - $dnsDomainNameProperty");
#Add instance back to workflow
$discoveryData.AddInstance($dbService);
#Create a relationship between this instance and the instance of DatabaseService
$dbRel = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.DatabaseServiceContainsDatabase']$");
$dbRel.Source = $dbService;
$dbRel.Target = $db;
#debug
$sDiscoveredItems = $sDiscoveredItems + $dbName + "`n";
#enddebug
#Add instance back to workflow
$discoveryData.AddInstance($dbRel);
}
#Loop through each public folder
$publicFolderDBs | foreach {
#We discovered a database, now create an instance
$db = $discoveryData.CreateClassInstance("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService']$");
#Populate the properties of the class and key properties of hosting classes
$db.AddProperty($componentNameProperty, $componentName);
$db.AddProperty($instanceNameProperty, $_.Name);
$db.AddProperty($displayNameProperty, $_.Name);
$db.AddProperty($principalNameProperty, $computerPrincipalName);
$db.AddProperty("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService']/DatabaseName$", $_.Name);
#Add instance back to workflow
$discoveryData.AddInstance($db);
#Create an instance of the DatabaseService class so we can link the two with a relationship
$dbName = $_.Name
$dbService = $discoveryData.CreateClassInstance("$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.DatabaseService']$");
$dbService.AddProperty("$MPElement[Name='MicrosoftExchange2010!Microsoft.Exchange.2010.Service']/ServiceName$", "Mailbox Database Service - $dbName - $dnsDomainNameProperty");
#Add instance back to workflow
$discoveryData.AddInstance($dbService);
#Create a relationship between this instance and the instance of DatabaseService
$dbRel = $discoveryData.CreateRelationshipInstance("$MPElement[Name='Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.DatabaseServiceContainsDatabase']$");
$dbRel.Source = $dbService;
$dbRel.Target = $db;
#debug
$sDiscoveredItems = $sDiscoveredItems + $dbName + "`n";
#enddebug
#Add instance back to workflow
$discoveryData.AddInstance($dbRel);
}
#debug
Write-Host $sDiscoveredItems
#$api.logscriptevent("DiscoverDBs.ps1",9898,4,$sDiscoveredItems)
#enddebug
#Return all instances back to OpsMgr agent
$discoveryData</ScriptBody>
<TimeoutSeconds>300</TimeoutSeconds>
</DataSource>
</Discovery>
</Discoveries>
<Monitors>
<UnitMonitor ID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup" Accessibility="Public" Enabled="true" Target="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.LastFullBackupMonitorType" ConfirmDelivery="true">
<Category>AvailabilityHealth</Category>
<AlertSettings AlertMessage="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup_AlertMessageResourceID">
<AlertOnState>Warning</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>MatchMonitorHealth</AlertSeverity>
<AlertParameters>
<AlertParameter1>$Data/Context/Property[@Name='LastFullBackupDays']$</AlertParameter1>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="UIGeneratedOpStateId5a42f14119624ef49578c932c0fe1ede" MonitorTypeStateID="Healthy" HealthState="Success" />
<OperationalState ID="UIGeneratedOpStateId8da552b98a8b441ab38e79eed3f8eb2d" MonitorTypeStateID="Warning" HealthState="Warning" />
<OperationalState ID="UIGeneratedOpStateIdf3e7f44b20f040c68b0afbb3b0c1af92" MonitorTypeStateID="Critical" HealthState="Error" />
</OperationalStates>
<Configuration>
<IntervalSeconds>43200</IntervalSeconds>
<TimeoutSeconds>120</TimeoutSeconds>
<Server>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</Server>
<WarningThresholdDays>7</WarningThresholdDays>
<CriticalThresholdDays>14</CriticalThresholdDays>
<DatabaseName>$Target/Property[Type="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService"]/DatabaseName$</DatabaseName>
</Configuration>
</UnitMonitor>
<UnitMonitor ID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted" Accessibility="Internal" Enabled="true" Target="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" TypeID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentHostedDBMountedMonitorType" ConfirmDelivery="true">
<Category>AvailabilityHealth</Category>
<AlertSettings AlertMessage="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted_AlertMessageResourceID">
<AlertOnState>Error</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>Error</AlertSeverity>
</AlertSettings>
<OperationalStates>
<OperationalState ID="UIGeneratedOpStateIde67ab2dce42745a89e573c8e2b679418" MonitorTypeStateID="Mounted" HealthState="Success" />
<OperationalState ID="UIGeneratedOpStateId46a3b584a8784c889da530083480f301" MonitorTypeStateID="NotMounted" HealthState="Error" />
</OperationalStates>
<Configuration>
<MBServer>$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/PrincipalName$</MBServer>
<DatabaseName>$Target/Property[Type="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService"]/DatabaseName$</DatabaseName>
<IntervalSeconds>300</IntervalSeconds>
<TimeoutSeconds>240</TimeoutSeconds>
</Configuration>
</UnitMonitor>
<DependencyMonitor ID="Custom.Example.Exchange.2010.MailboxMonitoring.Monitor.DatabaseHostAvailabilityRollup" Accessibility="Public" Enabled="true" Target="MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.DatabaseService" ParentMonitorID="Health!System.Health.AvailabilityState" Remotable="true" Priority="Normal" RelationshipType="Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.DatabaseServiceContainsDatabase" MemberMonitor="Health!System.Health.AvailabilityState">
<Category>AvailabilityHealth</Category>
<Algorithm>WorstOf</Algorithm>
</DependencyMonitor>
</Monitors>
</Monitoring>
<Presentation>
<Views>
<View ID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentMailboxView" Accessibility="Internal" Enabled="true" Target="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" TypeID="SC!Microsoft.SystemCenter.StateViewType" Visible="true">
<Category>StateCollection</Category>
<Criteria />
</View>
</Views>
<FolderItems>
<FolderItem ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentMailboxView" Folder="MicrosoftExchange2010!Microsoft.Exchange.2010.Mailbox.Folder" />
</FolderItems>
<StringResources>
<StringResource ID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup_AlertMessageResourceID" />
<StringResource ID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted_AlertMessageResourceID" />
</StringResources>
</Presentation>
<LanguagePacks>
<LanguagePack ID="ENU" IsDefault="true">
<DisplayStrings>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Datasource">
<Name>Exchange 2010 LastFullBackup Datasource</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentHostedDBMountedMonitorType">
<Name>Exchange 2010 Agent Hosted DB Mounted MonitorType</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.DS.MountedScriptCookdown">
<Name>Mounted Script Cookdown</Name>
<Description>Checks the state of the DBs and returns a separate property bag per DB.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.LastFullBackupMonitorType">
<Name>Exchange 2010 Mailbox Monitoring LastFullBackup Monitor Type</Name>
<Description />
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Probe">
<Name>Exchange 2010 LastFullBackup Probe</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Discovery.DiscoverAgentHostedDBs">
<Name>Agent Hosted Mounted Database Discovery</Name>
<Description>This discovery should discover the same instances as the DatabaseService class but it is hosted by the agent rather than the RMS or RMS Emulator. The discovery script runs by default once an hour, which is outside of the recommended frequency for a discovery.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService">
<Name>Mailbox Database Mounted (Agent Hosted)</Name>
<Description>This class should contain the same instances as the Microsoft.Exchange.2010.Mailbox.DatabaseService class except it is hosted by the Exchange Server rather than the RMS or RMS Emulator.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Class.Mailbox.HostedDatabaseService" SubElementID="DatabaseName">
<Name>Database Name</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.DatabaseServiceContainsDatabase">
<Name>Database Service Contains Agent Hosted Database Relationship</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.Relationship.WindowsComputerHostsDatabaseService">
<Name>Windows Computer Hosts Database Service Relationship</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring">
<Name>Exchange 2010 Mailbox Monitoring</Name>
<Description>Custom Exchange Monitoring</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup">
<Name>Exchange 2010 Mailbox Monitoring LastFullBackup Check</Name>
<Description>This monitor checks the LastFullBackup property of the Agent Hosted Mailbox to dtermine how long since the last backup. The monitor will change states based on the configured thresholds.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup" SubElementID="UIGeneratedOpStateId5a42f14119624ef49578c932c0fe1ede">
<Name>Healthy</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup" SubElementID="UIGeneratedOpStateId8da552b98a8b441ab38e79eed3f8eb2d">
<Name>Warning</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup" SubElementID="UIGeneratedOpStateIdf3e7f44b20f040c68b0afbb3b0c1af92">
<Name>Critical</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitor.LastFullBackup_AlertMessageResourceID">
<Name>Exchange 2010 Mailbox Monitoring LastFullBackup Check</Name>
<Description>The database has not been backed up for at least {0} days. </Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted">
<Name>Exchange 2010 Agent Hosted Database Mounted</Name>
<Description>This monitor determines if the agent hosted database is either mounted or dismounted.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted" SubElementID="UIGeneratedOpStateId46a3b584a8784c889da530083480f301">
<Name>NotMounted</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted" SubElementID="UIGeneratedOpStateIde67ab2dce42745a89e573c8e2b679418">
<Name>Mounted</Name>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.UnitMonitorAgentHostedDBMounted_AlertMessageResourceID">
<Name>Exchange 2010 Agent Hosted Database is Not Mounted</Name>
<Description>Exchange 2010 Agent Hosted database is not mounted.</Description>
</DisplayString>
<DisplayString ElementID="Custom.Example.Exchange.2010.MailboxMonitoring.AgentMailboxView">
<Name>Exchange 2010 Mailboxes (Agent Hosted)</Name>
</DisplayString>
</DisplayStrings>
<KnowledgeArticles></KnowledgeArticles>
</LanguagePack>
</LanguagePacks>
</ManagementPack>
Custom.Example.Exchange.2010.MailboxMonitoring.renametoxml
Comments
Anonymous
March 31, 2014
Hi Russ, I have imported this extended management pack. But I am unable to see the •Exchange 2010 Mailbox Monitoring LastFullBackup Check under the health explorer for Mailbox Database Service state. The monitor is enabled. Also the Exchange 2010 Agent Hosted Database Mounted monitor doesn't have a tick. I am wondering where went wrong? I do have the KHI: Database dismounted or service degraded monitor enabled.Anonymous
March 31, 2014
Hi Andrew, if you under MailboxExchange 2010 Mailboxes (Agent Hosted) do you see objects? If so if you go in health explorer for one of the objects do you see the monitors?Anonymous
March 31, 2014
Hi Russ, Under MailboxExchange 2010 Mailboxes (Agent Hosted), I do not see any objects. Did I miss something?Anonymous
March 31, 2014
The discovery either isn't working in your environment or hasn't ran yet. It runs a PowerShell script called DiscoverDBs.ps1. How long have you given it? It runs twice a day.Anonymous
April 01, 2014
I have given it one day but still nothing. Have ensured that in Authoring, the monitors for Exchange 2010 Agent Hosted Database Mounted is enabled. Under Mailbox Database Mounted (Agent Hosted), the monitors Exchange 2010 Agent Hosted Database Mounted and Exchange 2010 Mailbox Monitoring LastFullBackup are enabled. Still it doesn't show up at all in the Health Explorer.Anonymous
April 01, 2014
Hi Andrew. The discovery isn't working in your environment for some reason. Without the objects nothing will show up in health explorer. Send me a message and we'll take it offline. There is some debug logging you can enable in the discovery that might help, we can start with that.Anonymous
April 20, 2014
Andrew, I've updated the MP and it might resolve your issue, please let us know - Thanks!Anonymous
May 05, 2014
Will this MP work for Exchange 2013 as well? If not would it be possible to write one for 2013? ThanksAnonymous
May 05, 2014
Adam, the MP uses the Exchange 2010 MP for targeting and has relationships to classes in that MP, so it won't work with Exchange 2013. One could develop a similar MP for Exchange 2013 using the existing work already done in this MP but I currently don't have any plans to do this.Anonymous
June 25, 2014
The discovery is not working in our environment either, any advice on how we can troubleshoot?Anonymous
June 25, 2014
Sure Jetze, There is a powershell script in the management pack that runs some Exchange cmdlets. Either the cmdlets aren't returning the information we need or something else is happening in that script. You can try running parts of that script manually to troubleshoot.Anonymous
January 22, 2015
Hi there, I have a Problem. I want to build a MP that is ONLY verifying the Last- and Differential backup for a DAG (DatabaseAvailabilityGroup). The feed back should only be by DAG, or at least the servers should consolidated under the DAG (Tickets get automatically generated and we want to avoid several tickets for the same issue) If anyone could help me that would be so great. Thank you very much...