AK216292

Monitor_AK216292 (UnitMonitor)

Quarantined mailboxes detected on the computer

Knowledge Base article:

External

http://go.microsoft.com/fwlink/?LinkId=228586

Element properties:

TargetMicrosoft.KnowledgeServices.Exchange.2010.MailboxDatabase
Parent MonitorSystem.Health.ConfigurationState
CategoryAlert
EnabledTrue
Alert GenerateTrue
Alert SeverityWarning
Alert PriorityNormal
Alert Auto ResolveTrue
Monitor TypeMicrosoft.KnowledgeServices.Library.PowerShellMonitorEx
RemotableTrue
AccessibilityPublic
Alert Message
Quarantined mailboxes detected on the computer
<Details>
<Content>
One or more mailboxes have been found under the QuarantinedMailboxes Registry key. Identify the cause of the poison mailbox and correct the issue. Then manually reset the the registry key for the quarantined mailbox by deleting it. The registry path used for mailbox quarantine is HKLM\SYSTEM\CurrentControlSet\Services\MSExchangeIS\[Server Name]\Private-[db guid]\QuarantinedMailboxes\[mailbox guid]

</Content>
<CollectedInformation>
<Info>
<Name>Mailbox server</Name>
<Value>{0}</Value>
</Info>
<Info>
<Name>Mailbox database</Name>
<Value>{1}</Value>
</Info>
<Info>
<Name>Quarantined mailbox</Name>
<Value>{2}</Value>
</Info>
</CollectedInformation>
</Details>
RunAsDefault
CommentSupportTopic=TBD;VersionNumber=1.0.2.0;

Source Code:

<UnitMonitor ID="Monitor_AK216292" Comment="SupportTopic=TBD;VersionNumber=1.0.2.0;" Accessibility="Public" Enabled="true" Target="MicrosoftKnowledgeServicesExchange2010Library!Microsoft.KnowledgeServices.Exchange.2010.MailboxDatabase" ParentMonitorID="Health!System.Health.ConfigurationState" Remotable="true" Priority="Normal" TypeID="KnowledgeServicesLibrary!Microsoft.KnowledgeServices.Library.PowerShellMonitorEx" ConfirmDelivery="true">
<Category>Alert</Category>
<AlertSettings AlertMessage="MonitorMessagea245ca67abc64e178d7bd11a24a4f550">
<AlertOnState>Error</AlertOnState>
<AutoResolve>true</AutoResolve>
<AlertPriority>Normal</AlertPriority>
<AlertSeverity>Warning</AlertSeverity>
<AlertParameters>
<AlertParameter1>$Target/Property[Type="MicrosoftKnowledgeServicesExchange2010Library!Microsoft.KnowledgeServices.Exchange.2010.DatabaseInstance"]/ServerName$</AlertParameter1>
<AlertParameter2>$Target/Property[Type="MicrosoftKnowledgeServicesExchange2010Library!Microsoft.KnowledgeServices.Exchange.2010.DatabaseInstance"]/DatabaseName$</AlertParameter2>
<AlertParameter3>$Data/Context/Property[@Name='Mailboxes']$</AlertParameter3>
</AlertParameters>
</AlertSettings>
<OperationalStates>
<OperationalState ID="Success" MonitorTypeStateID="Success" HealthState="Success"/>
<OperationalState ID="Error" MonitorTypeStateID="Error" HealthState="Error"/>
</OperationalStates>
<Configuration>
<ScriptName>AK216292.ps1</ScriptName>
<Parameters>
<Parameter>
<Name>MailboxServer</Name>
<Value>$Target/Property[Type="MicrosoftKnowledgeServicesExchange2010Library!Microsoft.KnowledgeServices.Exchange.2010.DatabaseInstance"]/ServerName$</Value>
</Parameter>
<Parameter>
<Name>MailboxDatabase</Name>
<Value>$Target/Property[Type="MicrosoftKnowledgeServicesExchange2010Library!Microsoft.KnowledgeServices.Exchange.2010.DatabaseInstance"]/DatabaseName$</Value>
</Parameter>
</Parameters>
<ScriptBody><Script>


param($MailboxServer,$MailboxDatabase)

$ErrorActionPreference = "Stop"

# Set up the arguments
$scriptargs = new-object psobject
$scriptargs | add-member NoteProperty "MailboxServer" $MailboxServer
$scriptargs | add-member NoteProperty "MailboxDatabase" $MailboxDatabase

# Set up the output
$global:scriptoutput = new-object psobject
$scriptoutput | add-member NoteProperty "HasIssue" $false
$scriptoutput | add-member NoteProperty "MailboxServer" ""
$scriptoutput | add-member NoteProperty "MailboxDatabase" ""
$scriptoutput | add-member NoteProperty "Mailboxes" ""
#-----------------------------------------------------
# MAIN CODE SECTION
#-----------------------------------------------------

# Environment

$scriptenv = new-object psobject
$scriptenv | add-member NoteProperty "Mailbox" $null
$scriptenv | add-member NoteProperty "IsMailboxQuarantined" $false
$scriptenv | add-member NoteProperty "QuarantinedMailboxes" @()
$scriptenv | add-member NoteProperty "QuarantinedMailboxesList" @()
$scriptenv | add-member NoteProperty "MailboxDatabase" $null
$scriptenv | add-member NoteProperty "MailboxDatabaseGuid" ""
$scriptenv | add-member NoteProperty "MailboxServer" ""
$scriptenv | add-member NoteProperty "MailboxGuidList" @()
$scriptenv | add-member NoteProperty "MailboxGuid" ""
$scriptenv | add-member NoteProperty "MailboxRegKey" ""
$scriptenv | add-member NoteProperty "MailboxRegKey1" ""
$scriptenv | add-member NoteProperty "MailboxRegKey2" ""
$scriptenv | add-member NoteProperty "MailboxRegValue" $null
$scriptenv | Add-Member NoteProperty "CrashCount" 0
$scriptenv | Add-Member NoteProperty "CrashCountLimit" 3
$scriptenv | Add-Member NoteProperty "LastCrashFileTime" $null
$scriptenv | Add-Member NoteProperty "LastCrashDateTime" (Get-Date).AddSeconds(-26101)
$scriptenv | Add-Member NoteProperty "QuarantineDurationInSeconds" 21600

# Helper functions

# Function to read a regstry value
Function Get-RegistryValue(){
Param($key,$value)

$scriptenv.MailboxRegValue = Get-ItemProperty $key $value -ErrorAction SilentlyContinue
IF($scriptenv.MailboxRegValue -ne $null){
Return $scriptenv.MailboxRegValue.$value
}
Return $null
}

# Function to get Giud of a Mailbox
Function Get-MailboxDatabaseGuid(){
Param([string] $MailboxDatabaseName)

$scriptenv.MailboxDatabase = Get-MailboxDatabase -Identity $MailboxDatabaseName -ErrorAction SilentlyContinue
IF($scriptenv.MailboxDatabase -ne $null){
return $scriptenv.MailboxDatabase.Guid
}
else{
return ""
}
}

# Function to check whether a Mailbox is Quarantine Mailbox
Function Check-Mailbox(){
Param([string] $MailboxAlias)

$scriptenv.Mailbox = Get-Mailbox $MailboxAlias -ErrorAction SilentlyContinue
IF($scriptenv.Mailbox -ne $null){
$scriptenv.MailboxServer = $scriptenv.Mailbox.ServerName
$scriptenv.MailboxGuid = $scriptenv.Mailbox.ExchangeGuid
$scriptenv.MailboxDatabase = $scriptenv.Mailbox.Database
$scriptenv.MailboxDatabaseGuid = Get-MailboxDatabaseGuid $scriptenv.MailboxDatabase
$scriptenv.MailboxRegKey1 = "HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\" + $scriptenv.MailboxServer + "\Private-" + $scriptenv.MailboxDatabaseGuid
$scriptenv.MailboxRegKey2 = "HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\" + $scriptenv.MailboxServer + "\Private-" + $scriptenv.MailboxDatabaseGuid + "\QuarantinedMailboxes\" + $scriptenv.MailboxGuid

$scriptenv.CrashCountLimit = Get-RegistryValue $scriptenv.MailboxRegKey1 "MailboxQuarantineCrashThreshold"
If($scriptenv.CrashCountLimit -eq $null -or $scriptenv.CrashCountLimit -eq ""){
$scriptenv.CrashCountLimit = 3
}

$scriptenv.QuarantineDurationInSeconds = Get-RegistryValue $scriptenv.MailboxRegKey1 "MailboxQuarantineDurationInSeconds"
If($scriptenv.QuarantineDurationInSeconds -eq $null -or $scriptenv.QuarantineDurationInSeconds -eq ""){
$scriptenv.QuarantineDurationInSeconds = 21600
}

$scriptenv.CrashCount = Get-RegistryValue $scriptenv.MailboxRegKey2 "CrashCount"
If($scriptenv.CrashCount -eq $null -or $scriptenv.CrashCount -eq ""){
$scriptenv.CrashCount = 0
}

$scriptenv.LastCrashFileTime = Get-RegistryValue $scriptenv.MailboxRegKey2 "LastCrashTime"
If($scriptenv.LastCrashFileTime -eq $null -or $scriptenv.LastCrashFileTime -eq ""){
$scriptenv.LastCrashDateTime = (Get-Date).AddSeconds(-($scriptenv.QuarantineDurationInSeconds + 1))
}
else{
$scriptenv.LastCrashDateTime = [System.DateTime]::FromFileTime($scriptenv.LastCrashFileTime)
}
}
}

# Function to get all Quarantined Mailboxesinfo
Function Get-QuarantineMailboxes(){
Param($MailboxServer = [string]$scriptargs.MailboxServer, $MailboxDatabase = [string]$scriptargs.MailboxDatabase)

$scriptenv.MailboxDatabase = Get-MailboxDatabase -Identity $MailboxDatabase -ErrorAction SilentlyContinue

If($scriptenv.MailboxDatabase -ne $null){
$scriptenv.MailboxDatabaseGuid = $scriptenv.MailboxDatabase.Guid
}

$scriptenv.MailboxRegKey = "HKLM:\SYSTEM\CurrentControlSet\services\MSExchangeIS\" + $MailboxServer + "\Private-" + $scriptenv.MailboxDatabaseGuid + "\QuarantinedMailboxes"

$scriptenv.MailboxGuidList = Dir $scriptenv.MailboxRegKey -ErrorAction SilentlyContinue

Foreach($MailboxGuid in $scriptenv.MailboxGuidList){
if($MailboxGuid -ne $null){
If(-not ($MailboxGuid.Name).Endswith('QuarantinedMailboxes')){
$scriptenv.QuarantinedMailboxes += Get-MailBox -Identity ($MailboxGuid.Name.Substring($MailboxGuid.Name.LastIndexOf('\') + 1))
}
}
}

Foreach($Mailbox in $scriptenv.QuarantinedMailboxes){
Check-Mailbox $Mailbox.Alias
$scriptenv.IsMailboxQuarantined = $false

$scriptenv.IsMailboxQuarantined = (Get-MailboxStatistics -Identity $Mailbox.Alias -ErrorAction SilentlyContinue).IsQuarantined
If($scriptenv.IsMailboxQuarantined -eq $null ){
$scriptenv.IsMailboxQuarantined = $false
}
If (($scriptenv.CrashCount -ge $scriptenv.CrashCountLimit) -and (((Get-Date) - ($scriptenv.LastCrashDateTime)).TotalSeconds -lt $scriptenv.QuarantineDurationInSeconds) -and ($scriptenv.IsMailboxQuarantined -eq $true)){
$scriptenv.QuarantinedMailboxesList += [string]$scriptenv.Mailbox.Name
}
}

$scriptoutput.MailboxServer = $scriptargs.MailboxServer
$scriptoutput.MailboxDatabase = $scriptargs.MailboxDatabase
$scriptoutput.Mailboxes = [System.String]::Join(",",$scriptenv.QuarantinedMailboxesList)
}

# Main function

Function AdvisorRule($scriptargs, $scriptoutput)
{
# All parameters should be populated outside of the main function.
# The mian function should only include the detection logic so that it can be easyly reused by the Atlanta authoring tool.

# Initialize parameters
$scriptoutput.HasIssue = $false

# Set parameter values
Get-QuarantineMailboxes
# Detection Logic
If ($scriptenv.QuarantinedMailboxesList.Count -gt 0){
#Raise alert
$scriptoutput.HasIssue = $true
}

}
AdvisorRule $scriptargs $scriptoutput

# set the output
$mom = new-object -comobject "MOM.ScriptAPI"
$bag = $mom.CreatePropertyBag()

if ($scriptoutput.HasIssue -ne $null)
{
$bag.AddValue("HasIssue", $scriptoutput.HasIssue)
}

if ($scriptoutput.MailboxServer -ne $null)
{
$bag.AddValue("MailboxServer", $scriptoutput.MailboxServer)
}

if ($scriptoutput.MailboxDatabase -ne $null)
{
$bag.AddValue("MailboxDatabase", $scriptoutput.MailboxDatabase)
}

if ($scriptoutput.Mailboxes -ne $null)
{
$bag.AddValue("Mailboxes", $scriptoutput.Mailboxes)
}

$bag

</Script></ScriptBody>
<SnapIns>
<SnapIn>Microsoft.Exchange.Management.PowerShell.E2010</SnapIn>
</SnapIns>
<TimeoutSeconds>300</TimeoutSeconds>
<Schedule>86370</Schedule>
<ErrorExpression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</ErrorExpression>
<SuccessExpression>
<Not>
<Expression>
<SimpleExpression>
<ValueExpression>
<XPathQuery Type="Boolean">Property[@Name='HasIssue']</XPathQuery>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value Type="Boolean">true</Value>
</ValueExpression>
</SimpleExpression>
</Expression>
</Not>
</SuccessExpression>
</Configuration>
</UnitMonitor>