Wednesday, March 14, 2018

Monitoring Exchange 2013 and 2016 message queues with PowerShell

I’ve been asked several times in the past by colleagues how would they go about monitoring Exchange message queues so that they would be notified if a threshold is exceeded and while I usually recommend looking for this feature in their existing monitoring solution, an alternative and free method of achieving this is to use a PowerShell script with conjunction of the task scheduler.

What I’ve used in the past is to modify a script found here at the Microsoft Office TechCenter:

Powershell - Check Exchange 2010 Queue and mail alert on queue threshold

As this script was written for Exchange 2010, a slight modification to the line:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 

… would need to get changed to:

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;

The script would look as such for Exchange 2013 or 2016 (The variables you’ll need or could to change are highlighted in red):

$s = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri yourExchangeServer/PowerShell/ -Authentication Kerberos

Import-PSSession $s

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;

. $env:ExchangeInstallPath\bin\RemoteExchange.ps1

Connect-ExchangeServer -auto

$filename = “c:\Scripts\ExchangeQueues.txt

Start-Sleep -s 10

if (Get-ExchangeServer | Where { $_.isHubTransportServer -eq $true } | get-queue | Where-Object { $_.MessageCount -gt 30 })


Get-ExchangeServer | Where { $_.isHubTransportServer -eq $true } | get-queue | Where-Object { $_.MessageCount -gt 30 } | Format-Table -Wrap -AutoSize | out-file -filepath c:\Scripts\ExchangeQueues.txt

Start-Sleep -s 10

$smtpServer = “yourSMTPserver

$msg = new-object Net.Mail.MailMessage

$att = new-object Net.Mail.Attachment($filename)

$smtp = new-object Net.Mail.SmtpClient($smtpServer)

$msg.From = “





$msg.Subject = “Exchange queue threshold of 30 reached.

$msg.Body = “Please see attached queue log file for queue information




Note that the cmdlet used to check the queues can be modified to omit queues such as the Shadow Redundancy by adjusting:

if (Get-ExchangeServer | Where { $_.isHubTransportServer -eq $true } | get-queue | Where-Object { $_.MessageCount -gt 30 })

… into this:

if (Get-ExchangeServer | Where { $_.isHubTransportServer -eq $true } | get-queue | Where-Object { $_.MessageCount -gt 30 -and $_.DeliveryType -notlike "ShadowRedundancy"})

Adding the notlike operator will exclude the Shadow Redundancy queues when evaluating whether the threshold has been exceeded.

Once the script has been tested and verified to be in working order, you can then schedule it as a task to run every, say, 15 minutes as such:


Program/script: powershell.exe

Add arguments (optional): -command "& 'C:\Scripts\CheckExchangeQueues.ps1'"


No comments: