Description :

The script is intended to check for Exchange database update and transaction log copy problems. I have additionally added an event logging to the script. In fact I have created this script to log the Exchange database update and transaction log copy problems to the event log on the Exchange Servers and afterwards collect the event logs with SCOM and trigger the needed alerts. Of course you can remove the related part if you wish. If you want to use the script with SCOM you need to first create the related event log source as follows on the Exchange Server where you want to run the script. You can create the event source basically as follows.

#New-eventlog -logname Application -source “SCOM-Custom-DB-Queue-Checker”

The script is also available on Technet Script Repository for download :
https://gallery.technet.microsoft.com/scriptcenter/Check-for-Exchange-a3b7da5e

#*************************************************************************************************************
# ExchangeDatabaseQueueChecker.ps1
# Version 1.0
# Date: 06/02/2019
# Author: Cengiz KUSKAYA (www.Kuskaya.Info)
# Description: Powershell Script to check Exchange database update and transaction log copy problems.
#*************************************************************************************************************
Add-PSSnapin *E2010*

$CopyQueue_Threshold = 100 # copy queue is the indicator for transaction log copy problems from active to passive database, it can indicate network or service related problems.
$ReplayQueue_Threshold = 10 # replay is the database update, if its higher than threashold it indicate possible I/O problems.
$TCopyQueue_Threshold = 0
$TReplayQueue_Threshold = 0
$thrMsgcopy = “”
$thrMsgreplay = “”
$thrMsg= “”
$cwriteevent = 0
$rwriteevent = 0

$members = Get-DatabaseAvailabilityGroup
$members.Servers | ForEach-Object { Get-MailboxDatabaseCopyStatus -Server $_.Name | ForEach-Object {

$DB_Name = $_.Name;

$_.CopyQueueLength | ForEach-Object{
$copyQueueLength = $_

if ($copyQueueLength -gt $CopyQueue_Threshold){$cwriteevent=1}

$thrMsgcopy = $thrMsgcopy + “Database Queue Length: ” +$DB_Name + “: ” + $_ +”`n”;
}#copy queue limit forench region ends

$_.ReplayQueueLength | ForEach-Object{
$replayQueueLength = $_

if ($replayQueueLength -gt $ReplayQueue_Threshold){$rwriteevent=1}
$thrMsgreplay = $thrMsgreplay + “Database Queue Length: ” +$DB_Name + “: ” + $_+”`n”;
} #replay queue limit forench region ends

}
}

if ($cwriteevent -eq 1){
$message=”At least one or more databases copy queue length is more than ” + $CopyQueue_Threshold +”.” + “`n”+ $thrMsgcopy
Write-eventlog -logname Application -source SCOM-Custom-DB-Queue-Checker -eventID 11 -entrytype Error -message $message -EA SilentlyContinue;$message=””}
if ($rwriteevent -eq 1){
$message=”At least one or more databases replay queue length is more than ” + $ReplayQueue_Threshold +”.” + “`n”+ $thrMsgreplay
Write-eventlog -logname Application -source SCOM-Custom-DB-Queue-Checker -eventID 21 -entrytype Error -message $message -EA SilentlyContinue;$message=””}
if ($cwriteevent -eq 0){
$message = “Copy queue length is less than ” + $CopyQueue_Threshold + ” for all databases.” + “`n”+ $thrMsgcopy
Write-eventlog -logname Application -source SCOM-Custom-DB-Queue-Checker -eventID 10 -entrytype Information -message $message -EA SilentlyContinue}
if ($rwriteevent -eq 0){
$message = “Replay queue length is less than ” + $ReplayQueue_Threshold + ” for all databases.” + “`n”+ $thrMsgreplay
Write-eventlog -logname Application -source SCOM-Custom-DB-Queue-Checker -eventID 20 -entrytype Information -message $message -EA SilentlyContinue;$message=””}

Hope it helps !