Project Objective:
Monitor Exchange 2010 as well as Exchange 2003 message queues. This script can be deployed in a multiple scenarios with our without a Nagios or other monitoring enviroment.

Problem to be solved:
Increased monitoring of Exchange Server message queues. Get notified when messages are not leaving message queues.

Suggestions:
Monitor Exchange 2010 with native EMS Get-Queue command. – REJECTED, Too slow for monitoring system.
Monitor Exchange 2003 with previous VisualBasic Script check_msmq.wsf – REJECTED, One ring to rule them all!

#
# Watch-Exchange-Queues.ps1
#
# Written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)
#
# If you edit please keep my name as an original author and
# keep me apprised of the changes, see email address above.
# This code may not be used for commercial purposes.
# You the executor, runner, user accept all liability.
# This code comes with ABSOLUTELY NO WARRANTY.
# You may redistribute copies of the code under the terms of the GPL v2.
# -----------------------------------------------------------------------
# 2011.08.31 ver 3
#
# Summary:
# Checks number of messages in Exchange 2003 or 2010 message queues. If warning or
# critical thresholds are reached number of messages are outputted.
# -----------------------------------------------------------------------
# General Usage:
#    This script can be edited and or parameters can be passed to enable
#    email alerts, to whom, from whom, using what server, etc.
#     Examples:    
#        .\Watch-Exchange-Queues.ps1
#        .\Watch-Exchange-Queues.ps1 -email True -From foobar@null.local -To administrator@null.local -Server smtp.null.local
#
# Scheduled Task Usage
#    To run this script as a scheduled task create a .bat .cmd file
#    As indicated above you can either pass the needed parameters or
#    edit Watch-Exchange-Queues.ps1 itself. 
#    Example of .bat or .cmd file:
#        powershell -command "& '.\Watch-Exchange-Queues.ps1' -email True -From foobar@null.local -To administrator@null.local -Server smtp.null.local"
#
# Nagios Usage:
#    For Nagios NRPE/NSClient++ usage add the following line to the 
#    NSC.ini file after placing this script in Scripts subdirectory.
#    check_exch_mq=cmd /c echo scripts\Watch-Exchange-Queues.ps1; exit($lastexitcode) | powershell.exe -command -
#    NOTE: The trailing - is required.
# -----------------------------------------------------------------------
# Notes:
#    You may have asked "Why not use a more 'native' method to view the queue in Exchange 2010?"
#     Example: Get-ExchangeServer | where {$_.isHubTransportServer -eq $true} | get-queue | where {$_.MessageCount -gt 0} | measure-object MessageCount -max
#    Because the above requires the Exchange Managment Shell be loaded.
#     The shell loading is time consuming and thus the doesn't lend itself to a Nagios checks.
#    IF you want to go the 'native' route I suggest making a Scheduled Task then monitoring the tasks.
# -----------------------------------------------------------------------

# Optional Parameters and Editable Settings Used to Send E-mail Alert
Param(
    [string]$From = 'noreply@domain.ext',
    [string]$To = 'someone@domain.ext',
    [string]$Server = 'smtp.domain.ext',
    [int]$Port = 25,
    [string]$Username,
    [string]$Password,
    [switch]$email = $false,
    [switch]$SSL = $false
)

# Static Parameters
[int]$WarningLevel = 10
[int]$CriticalLevel = 20
[int]$ResultError = 0
[string]$computername=$env:computername


function Send-EmailMessage {
    param([string]$EmailSubj=$Results, [string]$EmailBody=$Results)
    $EmailMessage.Subject = $EmailSubj
    $EmailMessage.Body = $EmailBody
    $SMTPClient.Send( $EmailMessage )
}

# Exchange 2010 Check
$isHubTransportServer=(Test-Path "HKLM:\SOFTWARE\Microsoft\ExchangeServer\v14\HubTransportRole")
if ($isHubTransportServer) {
    $MessagesQueued=get-wmiobject -query "select MessagesQueuedForDelivery from Win32_PerfFormattedData_MSExchangeTransportQueues_MSExchangeTransportQueues"
    $Messages=$MessagesQueued.MessagesQueuedForDelivery
    if ($Messages) {
        if ($Messages -lt $WarningLevel) {
            $Results = 'No Alert. Number of messages in queue on '+$computername+': ' +$Messages
        }
        if ($Messages -gt $WarningLevel) {
            $ResultError=1
            $Results = 'WARNING ALERT! Number of messages in queue on '+$computername+': ' +$Messages
        }
        if ($Messages -gt $CriticalLevel) {
            $ResultError=2
            $Results = 'CRITICAL ALERT! Number of messages in queue on '+$computername+': ' +$Messages
        }
    }
    Else {
        $ResultError=1
        $Results = 'WARNING ALERT! Message Queue UNAVAILABLE on ' +$computername
    }
}

# Exchange 2003 (If no information or errors from above then check)
if (!($Results)) {
    $isExchange2003Server=get-wmiobject -query "Select Name From Win32_Service Where Name='MSExchangeSA'"
    if ($isExchange2003Server) {
        $ExchangeQueues=get-wmiobject -Namespace "root\cimv2\Applications\Exchange" -Query "SELECT NumberOfMessages FROM ExchangeQueue"
        foreach ($ExchangeQueue in $ExchangeQueues) {
            if (!($Messages)) { $Messages=$ExchangeQueue.NumberOfMessages  } 
            ELSE { $Messages=$Messages + $ExchangeQueue.NumberOfMessages }
        }

        if ($Messages) {
            if ($Messages -lt $WarningLevel) {
                $Results = 'No Alert. Number of messages in queue on '+$computername+': ' +$Messages
            }
            if ($Messages -gt $WarningLevel) {
                $ResultError=1
                $Results = 'WARNING ALERT! Number of messages in queue on '+$computername+': ' +$Messages
            }
            if ($Messages -gt $CriticalLevel) {
                $ResultError=2
                $Results = 'CRITICAL ALERT! Number of messages in queue on '+$computername+': ' +$Messages
            }
        }
        Else {
            $ResultError=1
            $Results = 'WARNING ALERT! Message Queue UNAVAILABLE on ' +$computername
        }
    }
    Else {
        $Results='No Alert. System is not an Exchange 2003 or 2010 Server with SMTP Message Queues.'
    }
}

if ($email) {
    $SMTPClient = New-Object Net.Mail.SMTPClient($Server, $Port)  
    if (($Username) -and ($Password)) { $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $Password) }
    if ($SSL) { $SMTPClient.EnableSSL = $true }
    $EmailMessage = New-Object System.Net.Mail.MailMessage
    $EmailMessage.From = $From
    $EmailMessage.To.Add( $To )
}

Switch ($ResultError) {
    default {
        write-host $Results
        exit 0
    }

    1 {
        write-host $Results
        if ($email) { Send-EmailMessage }
        exit 1
    }

    2 {
        write-host $Results
        if ($email) { Send-EmailMessage }
        exit 2
    } 
}
Be Sociable, Share!