Last active
July 4, 2018 00:18
-
-
Save theagreeablecow/5890371 to your computer and use it in GitHub Desktop.
SAMReport Module for Exchange
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Module Variables - Exchange # | |
#----------------------------------# | |
# Customise report Variables | |
$EmailTo = $EmailTo | |
$EmailSubject = $EmailSubject | |
$ReportTitle = $ReportTitle | |
$ReportSubTitle = $ReportSubTitle | |
# Load required plug-ins | |
if (!(Get-PSSnapin | where {$_.Name -eq "Microsoft.Exchange.Management.PowerShell.E2010"})){ | |
Write-Verbose "Loading the Exchange 2010 snapin" | |
try{ | |
Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 -ErrorAction STOP | |
} | |
catch{ | |
#Snapin not loaded | |
Write-Warning $_.Exception.Message | |
EXIT | |
} | |
. $env:ExchangeInstallPath\bin\RemoteExchange.ps1 | |
Connect-ExchangeServer -auto -AllowClobber | |
} | |
<# | |
FUTURE - NOT YET FUNCTIONAL | |
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://$Exchange_Server/PowerShell/ -Authentication Kerberos -Credential $Credentials | |
Import-PsSession $Session | |
#> | |
# Load server and array information | |
$ExchangeServers = @(Get-ExchangeServer | where {$_.ServerRole -ne "Edge"}) | |
$TransportServers = @(Get-TransportServer | where {$_.ServerRole -ne "Edge"}) | |
$CASServers = @(Get-ClientAccessServer) | |
$DAGs = @(Get-DatabaseAvailabilityGroup -Status) | |
<# | |
$OU = "OU=MyServers,DC=mydomain,DC=com,DC=au" | |
$Servers = Get-ADComputer -Filter {OperatingSystem -Like "Windows *Server*"} -SearchBase $OU | Select-Object –ExpandProperty Name | |
$Servers = @("Server1","Server2","Server3") | |
$Servers = Get-Content .\<path>\servers.txt | |
$Servers = ($env:COMPUTERNAME) | |
#> | |
#Miscellaneous |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Environment Summary" | |
$Comment = "This module shows an overview of the Exchange environment" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Thresholds | |
[int]$UpTimeMax = 180 #Days | |
[int]$UpTimeWarning = 90 #Days | |
#Create an Array and run query | |
$ResultsData = @() | |
#Ref: http://social.technet.microsoft.com/wiki/contents/articles/240.exchange-server-and-update-rollups-build-numbers.aspx | |
# http://social.technet.microsoft.com/wiki/contents/articles/15776.exchange-server-2013-and-cumulative-updates-cus-build-numbers.aspx | |
$VersionArray = ("Exchange Server 2010 RTM","14.00.0639.021"), | |
("Exchange Server 2010 Update Rollup 1","14.00.0682.001"), | |
("Exchange Server 2010 Update Rollup 2","14.00.0689.000"), | |
("Exchange Server 2010 Update Rollup 3","14.00.0694.000"), | |
("Exchange Server 2010 Update Rollup 4","14.00.0702.001"), | |
("Exchange Server 2010 Update Rollup 5","14.00.0726.000"), | |
("Exchange Server 2010 SP1 RTM","14.01.0218.015"), | |
("Exchange Server 2010 SP1 Update Rollup 1","14.01.0255.002"), | |
("Exchange Server 2010 SP1 Update Rollup 2","14.01.0270.001"), | |
("Exchange Server 2010 SP1 Update Rollup 3","14.01.0289.003"), | |
("Exchange Server 2010 SP1 Update Rollup 3 v3","14.01.0289.007"), | |
("Exchange Server 2010 SP1 Update Rollup 4","14.01.0323.001"), | |
("Exchange Server 2010 SP1 Update Rollup 4 v2","14.01.0323.006"), | |
("Exchange Server 2010 SP1 Update Rollup 5","14.01.0339.001"), | |
("Exchange Server 2010 SP1 Update Rollup 6","14.01.0355.002"), | |
("Exchange Server 2010 SP1 Update Rollup 7","14.01.0421.000"), | |
("Exchange Server 2010 SP1 Update Rollup 7 v2","14.01.0421.002"), | |
("Exchange Server 2010 SP1 Update Rollup 7 v3","14.01.0421.003"), | |
("Exchange Server 2010 SP1 Update Rollup 8","14.01.0438.000"), | |
("Exchange Server 2010 SP2 RTM","14.02.0247.005"), | |
("Exchange Server 2010 SP2 Update Rollup 1","14.02.0283.003"), | |
("Exchange Server 2010 SP2 Update Rollup 2","14.02.0298.004"), | |
("Exchange Server 2010 SP2 Update Rollup 3","14.02.0309.002"), | |
("Exchange Server 2010 SP2 Update Rollup 4","14.02.0318.002"), | |
("Exchange Server 2010 SP2 Update Rollup 4 v2","14.02.0318.004"), | |
("Exchange Server 2010 SP2 Update Rollup 5","14.02.0328.005"), | |
("Exchange Server 2010 SP2 Update Rollup 5 v2","14.02.0328.010"), | |
("Exchange Server 2010 SP2 Update Rollup 6","14.02.0342.003"), | |
("Exchange Server 2010 SP3 RTM","14.03.0123.004"), | |
("Exchange Server 2010 SP3 Update Rollup 1","14.03.0146.000"), | |
("Exchange Server 2010 SP3 Update Rollup 2","14.03.0158.001"), | |
("Exchange Server 2010 SP3 Update Rollup 3","14.03.0169.001"), | |
("Exchange Server 2010 SP3 Update Rollup 4","14.03.0174.001"), | |
("Exchange Server 2013 Preview","15.00.0466.013"), | |
("Exchange Server 2013 RTM","15.00.0516.032"), | |
("Exchange Server 2013 Cumulative Update 1","15.00.0620.029"), | |
("Exchange Server 2013 Cumulative Update 2","15.00.0712.024"), | |
("Exchange Server 2013 Cumulative Update 3","15.00.0775.038") | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
# Get Exchange Version | |
if ($Server.AdminDisplayVersion.Major -eq 14){ | |
$fileinfo = Get-Command "\\$Server\c$\program files\microsoft\exchange server\v14\bin\exsetup.exe" | %{$_.fileversioninfo} | |
} | |
elseif ($Server.AdminDisplayVersion.Major -eq 15){ | |
$fileinfo = Get-Command "\\$Server\c$\program files\microsoft\exchange server\v15\bin\exsetup.exe" | %{$_.fileversioninfo} | |
} | |
$FileVersion = $fileinfo.FileVersion | |
for($n=0;$n -lt $versionArray.count; $n++){ | |
if($FileVersion -eq $versionArray[$n][1]){ | |
$ExchangeVersion = $versionArray[$n][0] | |
} | |
} | |
#Trim Site Names | |
$Site = $Server.Site -replace "/Configuration/Sites/", " - " | |
#Format Build Date | |
$Created = ($Server.WhenCreated).ToString("dd/MM/yyyy") | |
#DNS Test | |
try { | |
$ip = @([System.Net.Dns]::GetHostByName($server).AddressList | Select-Object IPAddressToString -first 1 -ExpandProperty IPAddressToString) | |
} | |
catch{ | |
$IP = $NULL | |
} | |
if ($IP -eq $NULL){ | |
$DNS = "!RED!Failed" | |
$AlertText += "!RED!Unable to resolve IP Address for $Server </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
else{ | |
$DNS = "!GREEN!Passed" | |
} | |
#Ping Test | |
$PingTest = Test-Connection $Server -count 2 -Quiet -ErrorAction Stop | |
if ($PingTest -eq $False){ | |
$Ping = "!RED!Failed" | |
$AlertText += "!RED!Unable to ping IP Address for $Server </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
else{ | |
$Ping = "!GREEN!Passed" | |
} | |
#Uptime Test | |
$UpTime = $NULL | |
$LastBootUpTime = $NULL | |
$LastBootUpTime = [System.Management.ManagementDateTimeconverter]::ToDateTime((Get-WmiObject -Class Win32_OperatingSystem -computername $Server -ErrorAction Stop).LastBootUpTime) | |
[int]$UpTime = "{0:N0}" -f (New-TimeSpan $LastBootUpTime $Date).TotalDays | |
$UpTime = $UpTime + 1 | |
if ($UpTime -ge $UpTimeMax){ | |
$AlertText += "!RED!$Server has not been restarted for a VERY long time </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($UpTime -ge $UpTimeWarning){ | |
$WarningText += "!ORANGE!$Server has not been restarted for a long time </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
if ($UpTime -lt 1){ | |
$WarningText += "!ORANGE!$Server has been restarted in the past 24 hours </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#OS Version | |
$tWMI = Get-WmiObject Win32_OperatingSystem -ComputerName $Server -ErrorAction SilentlyContinue | |
if ($tWMI){ | |
$OSVersion = $tWMI.Caption.Replace("(R)","").Replace("Microsoft ","").Replace("Enterprise","Ent").Replace("Standard","Std").Replace(" Edition","") | |
$OSServicePack = $tWMI.CSDVersion | |
} | |
else { | |
$OSVersion = "N/A" | |
$OSServicePack = "N/A" | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $Server.Name | |
$obj | Add-Member -MemberType NoteProperty -name "Site" -value $Site | |
$obj | Add-Member -MemberType NoteProperty -name "Version" -value $ExchangeVersion | |
$obj | Add-Member -MemberType NoteProperty -name "Role(s)" -value $Server.ServerRole | |
$obj | Add-Member -MemberType NoteProperty -name "Edition" -value $Server.Edition | |
$obj | Add-Member -MemberType NoteProperty -name "Operating System" -value "$OSVersion $OSServicePack" | |
$obj | Add-Member -MemberType NoteProperty -name "Build Date" -value $Created | |
$obj | Add-Member -MemberType NoteProperty -name "DNS" -value $DNS | |
$obj | Add-Member -MemberType NoteProperty -name "Ping" -value $Ping | |
$obj | Add-Member -MemberType NoteProperty -name "Uptime" -value "$UpTime days" | |
$ResultsData += $obj | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Name" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Services Check" | |
$Comment = "This module checks that the appropriate services are running, according to the role(s) on each server" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
$FailedServices = @() | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
$ServiceHealth = @(Test-ServiceHealth $server -ErrorAction Stop) | |
foreach($Service in $ServiceHealth){ | |
$Failed = "" | |
$RoleName = $Service.Role | |
if ($Service.RequiredServicesRunning -eq $True){ | |
$Status = "Passed" | |
} | |
elseif ($Service.RequiredServicesRunning -eq $False){ | |
$Status = "Failed" | |
$FailedServices = $Service.ServicesNotRunning | |
ForEach ($FailedService in $FailedServices){ | |
$Failed += $FailedService | |
} | |
$AlertText += "!RED!Required services not running on $Server for $RoleName </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $Server.Name | |
$obj | Add-Member -MemberType NoteProperty -name "Role" -value $RoleName | |
$obj | Add-Member -MemberType NoteProperty -name "Service Health" -value $Status | |
$obj | Add-Member -MemberType NoteProperty -name "Services Not Running" -value $Failed | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Name" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Transport Queues" | |
$Comment = "This module checks for delayed messages in Transport Queues" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Thresholds | |
[int]$QueueMax = 100 | |
[int]$QueueWarning = 50 | |
#Create an Array and run query | |
$ResultsData = @() | |
$Queues = @() | |
# Add results into the array | |
foreach ($Server in $TransportServers){ | |
$Queues = Get-Queue -Server $Server | select-object Identity,DeliveryType,Status,MessageCount,LastRetryTime,NextRetryTime,NextHopDomain | |
foreach ($Queue in $Queues){ | |
#Message Count | |
$MessageCount = $Queue.MessageCount | |
if ($MessageCount -gt $QueueMax){ | |
$AlertText += "!RED!Exesive queue count for $Server </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($MessageCount -gt $QueueWarning){ | |
$AlertText += "!ORANGE!Long queue count for $Server </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $Server.Name | |
$obj | Add-Member -MemberType NoteProperty -name "Identity" -value $Queue.Identity | |
$obj | Add-Member -MemberType NoteProperty -name "Delivery Type" -value $Queue.DeliveryType | |
$obj | Add-Member -MemberType NoteProperty -name "Status" -value $Queue.Status | |
$obj | Add-Member -MemberType NoteProperty -name "Count" -value $MessageCount | |
$obj | Add-Member -MemberType NoteProperty -name "Last Retry" -value $Queue.LastRetryTime | |
$obj | Add-Member -MemberType NoteProperty -name "Next Retry" -value $Queue.NextRetryTime | |
$obj | Add-Member -MemberType NoteProperty -name "Next Hop" -value $Queue.NextHopDomain | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Name" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Database Mount Status" | |
$Comment = "This module checks the mount status of Public folder and Mailbox databases" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
$AllDBs = @() | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
if ($Server.IsMailboxServer -eq $True){ | |
$MailboxDBs = @(Get-MailboxDatabase -server $Server -status | Where {$_.MountedOnServer -eq ($Server.fqdn)}) | |
$PublicFolderDBs = @(Get-PublicFolderDatabase -server $Server -status) | |
$AllDBs = $MailboxDBs + $PublicFolderDBs | Select-object name,server,mounted,EdbFilePath,LogFolderPath | |
foreach ($DB in $AllDBs){ | |
#Unmounted DBs | |
if($DB.Mounted -eq $False){ | |
$DBName = $DB.Name | |
$AlertText += "!RED!$DBName is not mounted on $Server </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $DB.Name | |
$obj | Add-Member -MemberType NoteProperty -name "Mounted" -value $DB.Mounted | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $DB.Server | |
$obj | Add-Member -MemberType NoteProperty -name "EDB File" -value $DB.EdbFilePath | |
$obj | Add-Member -MemberType NoteProperty -name "Log Path" -value $DB.LogFolderPath | |
$ResultsData += $obj | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Name" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "DAG Database Health Status" | |
$Comment = "This module checks the health status of the Databases which are part of a Database Availability Group" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Thresholds | |
[int]$CopyQueueMax = 200 | |
[int]$CopyQueueWarning = 50 | |
[int]$ReplayQueueMax = 200 | |
[int]$ReplayQueueWarning = 50 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($DAG in $DAGs){ | |
#Get DAG databases and Copy Status | |
$DAGdb = @(Get-MailboxDatabase -Status | Where-Object {$_.MasterServerOrAvailabilityGroup -eq $DAG.Name} | Sort-Object Name) | |
foreach ($DB in $DAGdb) { | |
$DBCopyStatus = @($DB | Get-MailboxDatabaseCopyStatus) | |
foreach ($DBCopy in $DBCopyStatus){ | |
#Get Database Copy Info | |
$DBCopyName = $DBCopy.DatabaseName | |
$MailboxServer = $DBCopy.MailboxServer | |
$DBPreference = ($DB | Select-Object -ExpandProperty ActivationPreference | Where-Object {$_.Key -eq $MailboxServer}).Value | |
$CopyStatus = $DBCopy.Status | |
[int]$CopyQueueLength = $DBCopy.CopyQueueLength | |
[int]$ReplayQueueLength = $DBCopy.ReplayQueueLength | |
$ContentIndexState = $DBCopy.ContentIndexState | |
#Get Replay Lagged Info | |
$ReplayLagCopies = @($DB | Select -ExpandProperty ReplayLagTimes | Where-Object {$_.Value -gt 0}) | |
if ($($ReplayLagCopies.count) -gt 0){ | |
[bool]$ReplayLag = $False | |
foreach ($ReplayLagCopy in $ReplayLagCopies){ | |
if ($ReplayLagCopy.Key -eq $MailboxServer){ | |
[bool]$ReplayLag = $true | |
} | |
} | |
} | |
else{ | |
[bool]$ReplayLag = $false | |
} | |
#Get Truncation Lag Info | |
$TruncationLagCopies = @($DB | Select -ExpandProperty TruncationLagTimes | Where-Object {$_.Value -gt 0}) | |
if ($($TruncationLagCopies.count) -gt 0){ | |
[bool]$TruncateLag = $False | |
foreach ($TruncationLagCopy in $TruncationLagCopies){ | |
if ($TruncationLagCopy.Key -eq $MailboxServer){ | |
[bool]$TruncateLag = $True | |
} | |
} | |
} | |
else{ | |
[bool]$TruncateLag = $False | |
} | |
#Check Database Preference | |
if (($DBPreference -eq 1) -AND ($CopyStatus -ne 'Mounted')){ | |
$WarningText += "!ORANGE!$DBCopyName is not mounted on its preferred server </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check Copy Mount Status | |
if (($CopyStatus -ne "Mounted") -and ($CopyStatus -ne "Healthy")){ | |
$AlertText += "!RED!$DBCopyName is reporting a Copy Status of $CopyStatus on $MailboxServer</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Check Copy Queue Length | |
if ($CopyQueueLength -ge $CopyQueueMax){ | |
$AlertText += "!RED!$DBCopyName has a VERY high Copy Queue Length of $CopyQueueLength on $MailboxServer</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($CopyQueueLength -ge $CopyQueueWarning){ | |
$WarningText += "!ORANGE!$DBCopyName has a high Copy Queue Length of $CopyQueueLength on $MailboxServer</br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check Replay Queue Length | |
if ($ReplayQueueLength -ge $ReplayQueueMax){ | |
$AlertText += "!RED!$DBCopyName has a VERY high Replay Queue Length of $ReplayQueueLength on $MailboxServer</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($ReplayQueueLength -ge $ReplayQueueWarning){ | |
$WarningText += "!ORANGE!$DBCopyName has a high Replay Queue Length of $ReplayQueueLength on $MailboxServer</br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check Content Index State | |
if ($ContentIndexState -ne "Healthy"){ | |
$AlertText += "!RED!$DBCopyName is reporting a Content Index State of $ContentIndexState on $MailboxServer</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Database Copy" -value $DBCopyName | |
$obj | Add-Member -MemberType NoteProperty -name "Preference" -value $DBPreference | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $MailboxServer | |
$obj | Add-Member -MemberType NoteProperty -name "Status" -value $CopyStatus | |
$obj | Add-Member -MemberType NoteProperty -name "Copy Queue" -value $CopyQueueLength | |
$obj | Add-Member -MemberType NoteProperty -name "Replay Queue" -value $ReplayQueueLength | |
$obj | Add-Member -MemberType NoteProperty -name "Content Index" -value $ContentIndexState | |
$obj | Add-Member -MemberType NoteProperty -name "Replay Lagged" -value $ReplayLag | |
$obj | Add-Member -MemberType NoteProperty -name "Truncation Lagged" -value $TruncateLag | |
$ResultsData += $obj | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Database Copy","Preference" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "DAG Replication Health Status" | |
$Comment = "This module checks the health status of the Database Availability Group replication" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($DAG in $DAGs){ | |
$DAGMembers = @($DAG | Select-Object -ExpandProperty Servers | Sort-Object Name) | |
foreach ($DAGMember in $DAGMembers){ | |
$ReplicationHealth = Test-ReplicationHealth -Server $DAGMember | |
foreach ($HealthCheck in $ReplicationHealth){ | |
$CheckServer = $HealthCheck.Server | |
$CheckName = $HealthCheck.Check | |
$CheckResult = ($HealthCheck.Result).ToString() | |
$CheckError = $HealthCheck.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Passed"){ | |
$AlertText += "!RED!$CheckServer has failed the Replication Health Check $CheckName</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $CheckServer | |
$obj | Add-Member -MemberType NoteProperty -Name "Check" -Value $CheckName | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Name" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Backup status" | |
$Comment = "This module checks when each of the databases were last backed up" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
$Now = [DateTime]::Now | |
#Thresholds | |
[int]$LastBackupMax = 48 #Hours | |
[int]$LastBackupWarning = 24 #Hours | |
[int]$FullBackupMax = 14 #Days | |
[int]$FullBackupWarning = 7 #Days | |
#Create an Array and run query | |
$ResultsData = @() | |
$AllDBs = @() | |
$LastBackup = @{} | |
$Ago = @() | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
if ($Server.IsMailboxServer -eq $True){ | |
$MailboxDBs = @(Get-MailboxDatabase -server $Server -status | Where {$_.MountedOnServer -eq ($Server.fqdn)}) | |
$PublicFolderDBs = @(Get-PublicFolderDatabase -server $Server -status) | |
$AllDBs = $MailboxDBs + $PublicFolderDBs | |
foreach ($DB in $AllDBs){ | |
#Get all back up information | |
if ($DB.IsMailboxDatabase -eq $true) {$DBType = "Mailbox"} | |
if ($DB.IsPublicFolderDatabase -eq $true) {$DBType = "Public Folder"} | |
if ($DB.LastFullBackup -eq $null -and $DB.LastIncrementalBackup -eq $nul){ | |
$LastBackup.time = "Never" | |
$LastBackup.type = "Never" | |
[string]$Ago = "Never" | |
} | |
elseif ($DB.LastFullBackup -lt $DB.LastIncrementalBackup){ | |
$LastBackup.time = $DB.LastIncrementalBackup | |
$LastBackup.type = "Incremental" | |
[int]$Ago = ($Now - $LastBackup.time).Totalhours | |
$Ago = "{0:N0}" -f $Ago | |
} | |
elseif ($DB.LastIncrementalBackup -lt $DB.LastFullBackup){ | |
$LastBackup.time = $DB.LastFullBackup | |
$LastBackup.type = "Full" | |
[int]$Ago = ($Now - $LastBackup.time).Totalhours | |
$Ago = "{0:N0}" -f $Ago | |
} | |
#Check for Circular Logging | |
if ($DB.CircularLoggingEnabled -eq $True) { | |
$CircularLoggingEnabled="Yes" | |
} | |
else { | |
$CircularLoggingEnabled = "No" | |
} | |
#Days since last full backup | |
[int]$Age = ($Now - $DB.LastFullBackup).TotalDays | |
$Age = "{0:N0}" -f $Age | |
#Check age of last backup | |
if ($Ago -ge $LastBackupMax){ | |
$AlertText += "!RED!The last backup for $DB.name has not run for $Ago hours. </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($Ago -ge $LastBackupWarning){ | |
$AlertText += "!ORANGE!The last backup for $DB.name has not run for $Ago hours. </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check age of last Full backup | |
if ($Age -ge $FullBackupMax){ | |
$AlertText += "!RED!The last backup for $DB.name has not run for $Age days. </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($Age -ge $FullBackupWarning){ | |
$AlertText += "!ORANGE!The last backup for $DB.name has not run for $Age days. </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member NoteProperty -Name "Server/DAG" -Value $DB.MasterServerOrAvailabilityGroup | |
$obj | Add-Member NoteProperty -Name "Database" -Value $DB.name | |
$obj | Add-Member NoteProperty -Name "Database Type" -Value $DBType | |
$obj | Add-Member NoteProperty -Name "Last Backup Type" -Value $LastBackup.type | |
$obj | Add-Member NoteProperty -Name "Hours Since Last Backup" -Value $Ago | |
$obj | Add-Member NoteProperty -Name "Last Backup Time Stamp" -Value $LastBackup.time | |
$obj | Add-Member NoteProperty -Name "Days Since Full Backup" -Value $Age | |
$obj | Add-Member NoteProperty -Name "Circular Logging Enabled" -Value $CircularLoggingEnabled | |
$ResultsData += $obj | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server/DAG","Database" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Disk and Database Statistics" | |
$Comment = "This module checks database statistics and vailable disk space." | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
$Now = [DateTime]::Now | |
#Thresholds | |
[int]$MaxMailboxes = 1000 #Total Count | |
[int]$WarningMailboxes = 500 #Total Count | |
[int]$MaxDBSize = 1000 #GB | |
[int]$WarningDBsize = 750 #GB | |
[int]$MinFreeDisk = 5 #% | |
[int]$WarningFreeDisk = 10 #% | |
#Create an Array and run query | |
$ResultsData = @() | |
$AllDBs = @() | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
if ($Server.IsMailboxServer -eq $True){ | |
$MailboxDBs = @(Get-MailboxDatabase -server $Server -status | Where {$_.MountedOnServer -eq ($Server.fqdn)}) | |
foreach ($DB in $MailboxDBs){ | |
#Database Stats | |
$DBStats = get-mailboxdatabase $DB -status | Select-object databasesize,AvailableNewMailboxSpace,EdbFilePath,LogFolderPath | |
[INT]$DBSizeGB = ($DBStats.databasesize).ToGB() | |
[INT]$DBSizeMB = ($DBStats.databasesize).ToMB() | |
[INT]$WSSizeGB = ($DBStats.AvailableNewMailboxSpace).ToGB() | |
#Mailbox Stats | |
$MBXStats = get-mailboxdatabase $DB | Get-Mailbox -Resultsize Unlimited | select-object count | |
[INT]$MBXCount = $MBXStats.count | |
#Archive Stats | |
$ArchiveStats = get-mailboxdatabase $DB | Get-Mailbox -archive -Resultsize Unlimited | select-object count | |
[INT]$ArchiveCount = $ArchiveStats.count | |
#Average Size | |
[INT]$AllCount = $MBXCount + $ArchiveCount | |
[LONG]$AvgMBXSize = $DBSizeMB / $AllCount | |
# Disk Statistics | |
$DiskStats = @() | |
$DiskStats = Get-WmiObject win32_logicaldisk -computername $Server | Where-Object { $_.DriveType -eq 3 } | select DeviceID,FreeSpace,Size | |
$DBPath = ($DBStats.EdbFilePath).ToString() | |
$DBDisk = $DBPath.substring(0,2) | |
$LogPath = ($DBStats.LogFolderPath).ToString() | |
$LogDisk = $LogPath.substring(0,2) | |
foreach ($Disk in $DiskStats){ | |
$DiskID = $Disk.DeviceID | |
if ($DBDisk -eq $DiskID){ | |
$DBDiskFree = [Math]::Round($Disk.FreeSpace/1GB, 2) | |
$DBDiskSize = [Math]::Round($Disk.Size/1GB, 2) | |
$DBDiskPercentFree = [Math]::Round($DBDiskFree / $DBDiskSize * 100) | |
} | |
if ($LogDisk -eq $DiskID){ | |
$LogDiskFree = [Math]::Round($Disk.FreeSpace/1Gb) | |
$LogDiskSize = [Math]::Round($Disk.Size/1Gb) | |
$LogDiskPercentFree = [Math]::Round($LogDiskFree / $LogDiskSize * 100) | |
} | |
} | |
#Check number of mailbioxes | |
if ($AllCount -ge $MaxMailboxes){ | |
$AlertText += "!RED!There is a VERY large number of mailboxes on $Server. </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($AllCount -ge $WarningMailboxes){ | |
$AlertText += "!ORANGE!There is a large number of mailboxes on $Server. </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check database size | |
if ($DBSizeGB -ge $MaxDBSize){ | |
$AlertText += "!RED!The database $DB is VERY large. </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($DBSizeGB -ge $WarningDBsize){ | |
$AlertText += "!ORANGE!The database $DB is large. </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check Free Disk Space - Databases | |
if ($DBDiskPercentFree -le $MinFreeDisk){ | |
$AlertText += "!RED!$Server database disk ($DBDisk) only has $DBDiskPercentFree% free space remaining ($DBDiskFree GB free of $DBDiskSize GB). </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($DBDiskPercentFree -le $WarningFreeDisk){ | |
$AlertText += "!ORANGE!$Server database disk ($DBDisk) only has $DBDiskPercentFree% free space remaining ($DBDiskFree GB free of $DBDiskSize GB). </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Check Free Disk Space - Logs | |
if ($LogDiskPercentFree -le $MinFreeDisk){ | |
$AlertText += "!RED!$Server Logs disk ($LogDisk) only has $DBDiskPercentFree% free space remaining ($LogDiskFree GB free of $LogDiskSize GB). </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($LogDiskPercentFree -le $WarningFreeDisk){ | |
$AlertText += "!ORANGE!$Server Logs disk ($LogDisk) only has $DBDiskPercentFree% free space remaining ($LogDiskFree GB free of $LogDiskSize GB). </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member NoteProperty -Name "Server" -Value $Server | |
$obj | Add-Member NoteProperty -Name "Database" -Value $DB.name | |
$obj | Add-Member NoteProperty -Name "Mailbox Count" -Value $MBXCount | |
$obj | Add-Member NoteProperty -Name "Archive Count" -Value $ArchiveCount | |
$obj | Add-Member NoteProperty -Name "Avg. Mailbox Size" -Value "$AvgMBXSize MB" | |
$obj | Add-Member NoteProperty -Name "Database Size" -Value "$DBSizeGB GB" | |
$obj | Add-Member NoteProperty -Name "Whitespace" -Value "$WSSizeGB GB" | |
$obj | Add-Member NoteProperty -Name "Free DB Disk Space" -Value "$DBDiskPercentFree %" | |
$obj | Add-Member NoteProperty -Name "Free Log Disk Space" -Value "$LogDiskPercentFree %" | |
$ResultsData += $obj | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server/DAG","Database" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Check Mail FLow" | |
$Comment = "This module checks mail flow between each Mailbox server" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Thresholds | |
[int]$LatencyMax = 30 #Seconds | |
[int]$LatencyWarning = 10 #Seconds | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($SourceServer in $ExchangeServers){ | |
if ($SourceServer.IsMailboxServer -eq $True){ | |
$obj = New-Object PSObject | |
$obj | Add-Member NoteProperty -Name "Source Server" -Value $SourceServer.name | |
foreach ($TargetServer in $ExchangeServers){ | |
if ($TargetServer.IsMailboxServer -eq $True){ | |
try { | |
$Result = Test-Mailflow -Identity $SourceServer -TargetMailboxServer $TargetServer -ErrorAction Stop | |
} | |
catch{ | |
$msg = $_.Exception.Message | |
$AlertText += "!ORANGE!Message latency from $SourceServer to $TargetServer not tested due to an error.</br>" | |
$AlertText += "!ORANGE!$Msg</br>" | |
$WarningCount += $WarningCount.count + 1 | |
$Result = $null | |
} | |
if ($Result){ | |
[double]$Latency = "{0:N2}" -f $($Result.MessageLatencyTime.TotalSeconds) | |
$obj | Add-Member NoteProperty -Name "To $TargetServer (Secs)" -Value $Latency | |
} | |
else{ | |
$obj | Add-Member NoteProperty -Name "To $TargetServer (Secs)" -Value "Error" | |
$AlertText += "!RED!Unable to run Mailflow test from $SourceServer to $TargetServer </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Check latency Thresholds | |
if ($Latency -ge $LatencyMax){ | |
$AlertText += "!RED!Message latency from $SourceServer to $TargetServer is VERY high </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($Latency -ge $LatencyWarning){ | |
$AlertText += "!ORANGE!Message latency from $SourceServer to $TargetServer is high </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
} | |
} | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Source Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test MAPI Connectivity" | |
$Comment = "This module verifies server functionality for MAPI and LDAP" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($Server in $ExchangeServers){ | |
if ($Server.IsMailboxServer -eq $True){ | |
$MailboxDBs = @(Get-MailboxDatabase -server $Server -status | Where {$_.MountedOnServer -eq ($Server.fqdn)}) | |
foreach ($DB in $MailboxDBs){ | |
$MAPIHealth = Get-MailboxDatabase $DB | Test-MapiConnectivity | |
foreach ($HealthCheck in $MAPIHealth){ | |
$CheckServer = $HealthCheck.Server | |
$CheckDB = $HealthCheck.Database | |
$CheckResult = ($HealthCheck.Result).ToString() | |
$CheckError = $HealthCheck.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$CheckServer has failed the MAPI Health Check on $CheckDB</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $CheckServer | |
$obj | Add-Member -MemberType NoteProperty -Name "Database" -Value $CheckDB | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
} | |
} | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test OWA Connectivity" | |
$Comment = "This module verifies server functionality for Outlook Web Access" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
$URL = "https://exchange.mydomain.com.au/owa" | |
# Add results into the array | |
$OWAHealth = Test-OwaConnectivity –URL $URL -MailboxCredential $Credentials -TrustAnySSLCertificate | |
$CheckURL = $OWAHealth.URL | |
$CheckResult = ($OWAHealth.Result).ToString() | |
$CheckLatency = $OWAHealth.Latency | |
$CheckError = $OWAHealth.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$CheckServer has failed the OWA Health Check</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -Name "URL" -Value $CheckURL | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Latency" -Value $CheckLatency | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test Web Services Connectivity" | |
$Comment = "This module verifies server functionality for Web Services (Outlook Anywhere)" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($Server in $CASServers){ | |
$WebHealth = Test-WebServicesConnectivity –ClientAccessServer $Server –MailboxCredential $Credentials -TrustAnySSLCertificate | |
foreach ($HealthCheck in $WebHealth){ | |
$CheckServer = $Server | |
$CheckScenario = $HealthCheck.Scenario | |
$CheckResult = ($HealthCheck.Result).ToString() | |
$CheckLatency = $HealthCheck.Latency | |
$CheckError = $HealthCheck.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$CheckServer has failed the Web Services Health Check</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $CheckServer | |
$obj | Add-Member -MemberType NoteProperty -Name "Scenario" -Value $CheckScenario | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Latency" -Value $CheckLatency | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test POP Connectivity" | |
$Comment = "This module verifies server functionality for POP3" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($Server in $CASServers){ | |
$POPHealth = Test-PopConnectivity –ClientAccessServer $Server –MailboxCredential $Credentials -TrustAnySSLCertificate | |
foreach ($HealthCheck in $POPHealth){ | |
$CheckServer = $Server | |
$CheckScenario = $HealthCheck.Scenario | |
$CheckResult = ($HealthCheck.Result).ToString() | |
$CheckLatency = $HealthCheck.Latency | |
$CheckError = $HealthCheck.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$CheckServer has failed the POP3 Health Check</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $CheckServer | |
$obj | Add-Member -MemberType NoteProperty -Name "Scenario" -Value $CheckScenario | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Latency" -Value $CheckLatency | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test IMAP Connectivity" | |
$Comment = "This module verifies server functionality for IMAP4" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($Server in $CASServers){ | |
$IMAPHealth = Test-ImapConnectivity –ClientAccessServer $Server –MailboxCredential $Credentials -TrustAnySSLCertificate | |
foreach ($HealthCheck in $IMAPHealth){ | |
$CheckServer = $Server | |
$CheckScenario = $HealthCheck.Scenario | |
$CheckResult = ($HealthCheck.Result).ToString() | |
$CheckLatency = $HealthCheck.Latency | |
$CheckError = $HealthCheck.Error | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$CheckServer has failed the IMAP Health Check</br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $CheckServer | |
$obj | Add-Member -MemberType NoteProperty -Name "Scenario" -Value $CheckScenario | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$obj | Add-Member -MemberType NoteProperty -Name "Latency" -Value $CheckLatency | |
$obj | Add-Member -MemberType NoteProperty -Name "Error" -Value $CheckError | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Server" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test SMTP Connectivity" | |
$Comment = "This module verifies server functionality for SMTP" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
#Create an Array and run query | |
$ResultsData = @() | |
# Add results into the array | |
foreach ($Server in $TransportServers){ | |
$SMTPHealth = Test-SMTPConnectivity –Identity $Server | |
foreach ($HealthCheck in $SMTPHealth){ | |
$CheckConnector = $HealthCheck.ReceiveConnector | |
$CheckBinding = $HealthCheck.Binding | |
$CheckEndpoint = $HealthCheck.Endpoint | |
$CheckResult = ($HealthCheck.StatusCode).ToString() | |
#Check for any Failures | |
if ($CheckResult -ne "Success"){ | |
$AlertText += "!RED!$Server has failed a SMTP Health Check from $CheckConnector to $CheckEndpoint. </br>" | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -Name "Receive Connector" -Value $CheckConnector | |
$obj | Add-Member -MemberType NoteProperty -Name "Binding" -Value $CheckBinding | |
$obj | Add-Member -MemberType NoteProperty -Name "Endpoint" -Value $CheckEndpoint | |
$obj | Add-Member -MemberType NoteProperty -Name "Result" -Value $CheckResult | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Receive Connector" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Test System Health" | |
$Comment = "This module analyses your environment according to best practices" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
[int]$AlertCount = 0 | |
[int]$WarningCount = 0 | |
# Run test and add results to XMl file | |
$Test = Test-SystemHealth -OutData | |
Set-Content -Value $Test.FileData -Path "$OutputFolder\SystemHealthOutData_$Date.xml" -Encoding Byte | |
if ($output -eq "OnScreen"){ | |
$ResultsText = "System Health analysis completed. Please import the results file ($OutputFolder\SystemHealthOutData.xml) into the Best Practices Analyser tool" | |
} | |
elseif ($output -eq "Email"){ | |
$ResultsText = "System Health analysis completed. Please import the attached XML results into the Best Practices Analyser tool" | |
} | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = "" # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "$OutputFolder\SystemHealthOutData_$Date.xml" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "Event Logs" | |
$Comment = "Event Log entries that match defined criteria" | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Create an Array and run query | |
$ResultsData = @() | |
$AlertData = @() | |
$WarningData = @() | |
#Define Event Log Queries | |
<# | |
TIP: | |
- Customise queries via Event Viewer > Create Custom View > Copy query string from XML tab | |
- Ensure to choose a time frame that matches your reporting period eg 'Last 24 Hours' | |
#> | |
$AlertXML = '<QueryList> | |
<Query Id="0" Path="Application"> | |
<Select Path="Application">*[System[(Level=1 or Level=2) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
<Select Path="System">*[System[(Level=1 or Level=2) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
<Select Path="MSExchange Management">*[System[(Level=1 or Level=2) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
</Query> | |
</QueryList>' | |
$WarningXML = '<QueryList> | |
<Query Id="0" Path="Application"> | |
<Select Path="Application">*[System[(Level=3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
<Select Path="System">*[System[(Level=3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
<Select Path="MSExchange Management">*[System[(Level=3) and TimeCreated[timediff(@SystemTime) <= 86400000]]]</Select> | |
</Query> | |
</QueryList>' | |
#Add data to array | |
foreach ($Server in $ExchangeServers){ | |
#Event Log Alerts | |
$AlertEvents = Get-WinEvent -ea SilentlyContinue -ComputerName $Server -Filterxml $AlertXML | |
ForEach ($LogEntry in $AlertEvents) { | |
if ($LogEntry.Level -eq 1){$LevelTxt = "!RED!Critical"} | |
elseif ($LogEntry.Level -eq 2){$LevelTxt = "!RED!Error"} | |
elseif ($LogEntry.Level -eq 3){$LevelTxt = "!ORANGE!Warning"} | |
else {$LevelTxt = "Info"} | |
if ($LogEntry.Message.Length -ge 75){$Msg = $LogEntry.Message.substring(0,75)} | |
else {$Msg = $LogEntry.Message} | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Server" -value $Server | |
$obj | Add-Member -MemberType NoteProperty -name "Level" -value $LevelTxt | |
$obj | Add-Member -MemberType NoteProperty -name "Logged" -value $LogEntry.TimeCreated | |
$obj | Add-Member -MemberType NoteProperty -name "Source" -value $LogEntry.ProviderName | |
$obj | Add-Member -MemberType NoteProperty -name "ID" -value $LogEntry.ID | |
$obj | Add-Member -MemberType NoteProperty -name "Event Data" -value $Msg | |
$AlertData += $obj | |
$AlertCount += $AlertCount.count + 1 | |
} | |
#Event Log Warnings | |
$WarningEvents = Get-WinEvent -ea SilentlyContinue -ComputerName $Server -Filterxml $WarningXML | |
ForEach ($LogEntry in $WarningEvents) { | |
if ($LogEntry.Level -eq 1){$LevelTxt = "!RED!Critical"} | |
elseif ($LogEntry.Level -eq 2){$LevelTxt = "!RED!Error"} | |
elseif ($LogEntry.Level -eq 3){$LevelTxt = "!ORANGE!Warning"} | |
else {$LevelTxt = "Info"} | |
if ($LogEntry.Message.Length -ge 75){$Msg = $LogEntry.Message.substring(0,75)} | |
else {$Msg = $LogEntry.Message} | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Computer" -value $Server | |
$obj | Add-Member -MemberType NoteProperty -name "Level" -value $LevelTxt | |
$obj | Add-Member -MemberType NoteProperty -name "Logged" -value $LogEntry.TimeCreated | |
$obj | Add-Member -MemberType NoteProperty -name "Source" -value $LogEntry.ProviderName | |
$obj | Add-Member -MemberType NoteProperty -name "ID" -value $LogEntry.ID | |
$obj | Add-Member -MemberType NoteProperty -name "Event Data" -value $Msg | |
$AlertData += $obj | |
$WarningCount += $WarningCount.count + 1 | |
} | |
} | |
# Results Data | |
$ResultsData = $AlertData + $WarningData | sort -Property "Logged" | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = "" # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
$Attachment = "" # $Attachment MUST be either UNC path or "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################################################ | |
# Info # | |
#------------------------ | |
$Title = "ActiveSync - Device Count per User" | |
$Comment = "This module checks the total number of EAS devices against the maximum device limit." | |
$Author = "The Agreeable Cow" | |
$PluginDate = "09/06/2013" | |
$Version = "v1.0" | |
# 1.0 09/06/2013 The Agreeable Cow Original Build | |
############################################################################################################ | |
# Main Script # | |
#------------------------ | |
#Reset Counters | |
$AlertText = "" | |
$WarningText = "" | |
$AlertCount = 0 | |
$WarningCount = 0 | |
<# | |
TIP: The default EasMaxDevices is 10 devices per user. | |
Enable the $PurgeOldDevices option below to remove devices for individuals that have not connected for a specified period of time. | |
#> | |
#Thresholds | |
$Policy = Get-Throttlingpolicy | where {$_.IsDefault -eq $TRUE} | select-object EasMaxDevices | |
[int]$MaxDevices = $Policy.EasMaxDevices | |
[int]$AlertDevices = 0.90 * $MaxDevices #eg 0.90 * 10 will alert on 9 devices | |
[int]$WarningDevices = 0.70 * $MaxDevices #eg 0.70 * 10 will warn on 7 devices | |
[int]$ReportMinimum = 0.50 * $MaxDevices #eg 0.50 * 10 wil report on 5 or more devices | |
$PurgeOldDevices = $TRUE # $TRUE or $FALSE | |
$PurgeAge = 180 # If Alerting and $PurgeOldDevices = $TRUE, Devices that have not connected for this many days, will be removed | |
$EASLogFile = "$OutputFolder\PurgedEASDevices_$Date.txt" | |
#Create an Array and run query | |
$ResultsData = @() | |
$EASMailboxes = Get-CASMailbox -Filter {HasActiveSyncDevicePartnership -eq $True -and DisplayName -notlike "CAS_{*"} | Get-Mailbox | |
# Add results into the array | |
foreach ($Mailbox in $EASMailboxes){ | |
$EASInfo = $Mailbox | Select-Object SamAccountName, DisplayName, PrimarySMTPAddress, @{Name="EASDeviceCount";Expression={(Get-ActiveSyncDevice -Mailbox $_.Identity).Count}} | |
#Get users with enough devices to report on | |
if ($EASInfo.EASDeviceCount -ge $ReportMinimum){ | |
$Name = $EASInfo.DisplayName | |
#Get excesive devices | |
if ($EASInfo.EASDeviceCount -ge $AlertDevices){ | |
#Purge old devices | |
if ($PurgeOldDevices -eq $TRUE){ | |
$DevicesToPurge = Get-ActiveSyncDevice -Mailbox $Mailbox | Get-ActiveSyncDeviceStatistics | where {$_.LastSuccessSync -le (Get-Date).AddDays(-$PurgeAge)} | |
$RemoveCount = 0 | |
foreach($Device in $DevicesToPurge){ | |
$Log = $TRUE | |
$RemoveCount += $RemoveCount.Count + 1 | |
$DeviceID = $Device.Identity | |
$Model = $Device.DeviceModel | |
$LastSync = $Device.LastSuccessSync | |
write-output ("Device Purged $Date: `t $Name, $DeviceID, $Model, $LastSync") | out-file $EASLogFile -append | |
Remove-ActiveSyncDevice ([string]$Device.Guid) -confirm:$false | |
} | |
#Reporting | |
if ($RemoveCount -ge 1){ | |
$AlertText += "!RED!$Name has an excessive number of ActiveSync Devices. $RemoveCount device(s) purged being older than $PurgeAge days. Please see attached log. </br>" | |
} | |
else{ | |
$AlertText += "!RED!$Name has an excessive number of ActiveSync Devices </br>" | |
} | |
} | |
else{ | |
$AlertText += "!RED!$Name has an excessive number of ActiveSync Devices </br>" | |
} | |
$AlertCount += $AlertCount.count + 1 | |
} | |
elseif ($EASInfo.EASDeviceCount -ge $WarningDevices){ | |
$WarningText += "!ORANGE!$Name has a large number of ActiveSync Devices </br>" | |
$WarningCount += $WarningCount.count + 1 | |
} | |
#Build Array | |
$obj = New-Object PSobject | |
$obj | Add-Member -MemberType NoteProperty -name "Name" -value $Name | |
$obj | Add-Member -MemberType NoteProperty -name "Email Address" -value $EASInfo.PrimarySMTPAddress | |
$obj | Add-Member -MemberType NoteProperty -name "Device Count" -value $EASInfo.EASDeviceCount | |
$ResultsData += $obj | |
} | |
} | |
# Results Text | |
if ($AlertText -ne $null -or $WarningText -ne $null){ | |
$ResultsText = $AlertText + $WarningText | |
} | |
else{ | |
$ResultsText = "" | |
} | |
# Results Data | |
$ResultsData = $ResultsData | sort -Property "Device Count" -Descending | |
# Results Alert | |
if ($AlertCount -ge 1){ | |
$ResultsAlert = "Alert" | |
} | |
elseif ($WarningCount -ge 1){ | |
$ResultsAlert = "Warning" | |
} | |
else{ | |
$ResultsAlert = "Good" | |
} | |
############################################################################################################ | |
# Output # | |
#------------------------ | |
$OutText = $ResultsText # $OutText MUST be either $ResultsText or "" Valid $ResultsText is any text string | |
$OutData = $ResultsData # $OutData MUST be either $ResultsData or "" Valid $ResultsData is any data array | |
$OutAlert = $ResultsAlert # $OutAlert MUST be either $ResultsAlert or "" Valid $ResultsAlert are 'Good', 'Warning' or 'Alert' | |
if ($Log -eq $TRUE){ | |
$Attachment = $EASLogFile # $Attachment MUST be either UNC path or "" | |
} | |
else{ | |
$Attachment = "" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment