Monitoring Exchange 2007 / 2010 with Powershell (Part 4)

If you would like to read the other parts in this article series please go to:

Introduction

In the first part of this series we highlighted that the ability to know what is happening on your Exchange Servers quickly and accurately is key to effective Exchange Administration.

In the second part we began to construct a script that when completed could be scheduled via the Windows Task Scheduler to monitor some basic aspects of your Exchange environments – in the second part we defined the following functions:

  • Checking CPU Utilisation
  • Checking Free Memory
  • Checking Event Logs
  • Checking each server for specific Exchange Roles and executing the relevant tests

In the third instalment we added functionality to the script in the form of:

  • Checking the status of Exchange related Services
  • Defining a function that will perform a number of Mailbox Role tests
  • DiskspaceTests
  • Database BackupTests

In this the final part we will round off the script by:

  • Define health checking functions for the CAS and HT roles
  • Put the whole script together in a single file for download
  • Explain how you can schedule the script
  • Add a few suggestions for further development

Checking Hub Transport Role

The purpose of the HT Role checking function is naturally to provide some basic information about the health of mail transport within your organisation.

The function itself is called from the check_roles () function and determines all of the queues which are resident on the Hub Transport Server(s) that are passed to the function from the ExchangeServers.txt file.

The function then compares the amount of messages awaiting processing in those queues against the threshold value that is stored in the $QueueMessageUpperLevel global constant. If the number of messages in the queue is greater than the global constant an alert is sent to the administrator.

The number of messages in each queue on the transport server is determined by using the Get-Queue function in a variable called $AvailableQueues.

Then using a for each loop we cycle through the queues in the $AvailableQueues variable checking the number of messages contained within – we then use an if statement to invoke the SMTPAlertMessage function if needed.

We finish off the function by checking disk space on the HT server (the checkDiskSpaceFree function was detailed in part 3 of the series).

functionHTRoleTest($strHTServer){

$AvailableQueues=Get-Queue-Server$strHTServer

Foreach($Queuein$AvailableQueues){

if($Queue.MessageCount -gt$QueueMessageUpperLevel){

$MessBody="The following Transport Queue: "+$Queue.Identity +" has exceed the maximum permissible message count with "+$Queue.MessageCount

SMTPAlertMessage"Exchange Transport Queue Error"$MessBody

}

}

checkDiskSpaceFree$strHTServer

}

Checking the CAS role

The CASRoleTest function purpose is to check the basic health of the Client Access Function. Now you might expect me to make use of the Test-Outlookweb Services or Test-OWAConnectivity within this function – and indeed as part of the developments section of this article I do suggest that this functionality is added.

However in the context of web connectivity I have focussed on actually checking to see if you can establish a connection and hit a webpage on your Client Access Server.

In essence I establish a .Net Web Request to a URL on the client access server (the URL is defined in $URL – this can be changed to fit your own personal configuration. I then attempt to make a connection to that URL. If the result of that connection is anything other than Status 200 (OK) then the script sends an alert to the administrator.

If I cannot make a http request to the CAS (e.g. if the IIS service is down) the GetResponse() with throw an exception – therefore using the try{}catch{} exception handling – the code in the }catch{ segment is invoked – this will send an alert message to the administrator suggesting that the IIS service has terminated or is down.

You could expand the functionality of this function at this point by adding in some more detailed testing using the Test-OwaConnectivity or Test-OutlookWebServices should you wish.

I finish off the function by performing a very basic MAPI connectivity test using the Test-MAPIConnectivity cmdlet.

functionCASRoleTest($strCASServer){

# Change the URL below to your internal OWA instance

$URL="https://owa.justice.lab.local"

$webRequest= [net.WebRequest]::Create($URL)

checkDiskSpaceFree$strCASServer

try{

$response=$webRequest.GetResponse()

Write-Host"Testing OWA Site"-ForegroundColorCyan

if($response.statusCode -ne 200){

$MessBody="There appears to be a problem with the IIS instance of $URL - testing of the instance returns Status code: "+$response.statusCode

SMTPAlertMessage"Exchange CAS Error"$MessBody

}

}catch{

Write-Host"Testing OWA Site"-ForegroundColorMagenta

$MessBody="There appears to be a problem with the IIS Service of $URL - Cannot connect to Service"

SMTPAlertMessage"Exchange CAS Error"$MessBody

}

$MAPI=Test-MAPIConnectivity-Server$strCASServer

Write-Host"Testing MAPI"-ForegroundColorMagenta

foreach($MapiEndPointin$MAPI){

if($MapiEndPoint.Result -ne"Success"){

$MessBody="There appears to be a problem with MAPI Connectivity on: "+$MapiEndPoint.Server +" Context: "+$MapiEndPoint.Database +" Error: "+$MapiEndPoint.Error

SMTPAlertMessage"Exchange CAS Error"$MessBody

}

}

}

The completed script

You can download the compressed version of the completed script with all the functions in order from the following location:

MSEXMon_Demo.ps1

Using and Scheduling the Script

In order to make use of the script in your environment please use the following steps –

  1. Download it to an Exchange Server of your choosing
  2. In the same folder as the script – create a file called “ExchangeServers.txt
  3. Within the ExchangeServers.txt file – add the NETBIOS names of each Exchange Server that you would like to monitor. Each server should be placed on a new line within the file
  4. Save and close the file
  5. Open the script and add the following line at the top
    Add-PSSnapinMicrosoft.Exchange.Management.PowerShell.Admin
  6. Within the script file change the following lines:
    ExServers=Get-Content"x:\ExMon\ExchangeServers.txt"
    $SMTPHost="172.31.253.136"
    To the location of the ExchangeServers.txt file and an appropriate SMTP smart host within your environment.
    You should also modify the following thresholds to acceptable values for monitoring:
    # Set global Constants
    $DBSizeThreshold= 200                           # In MB
    $PDBSizeThreshold= 200                          # In MB
    $lastBackupThreshhold= 1                        # In days
    $DiskspacePercentageFree= 10                           # In %
    $QueueMessageUpperLevel= 5                      # In Number of Messages
    $MemoryThreshold= 800                           # MB Free
    $CPU_UpperLeverPercentage= 20                   # Utilisation over sample period
    You should also change the values in the SMTPAlertMessagefunction to reflect your administrator account within your organisation:
    From ="psExchangeMonitoringAgent@seg.com"
    To ="psExchangeMonitoring@seg.com"
  7. Save and close the script file
  8. Ensure that the Execution Policy for PowerShell is set to “Remote Signed”
    Open a PowerShell command prompt and type “Set-ExecutionPolicy RemoteSigned”
  9. Create a batch file called “ExMon.bat” on your Exchange Server and add the following lines:
    @Echo Off
    @Powershell –command “& {<path to script>\MSEXMON_DEMO.ps1}”
    See example below:

    Figure 1
  10. Save the file to a location on your Exchange Server
  11. Use the Windows Task scheduler to execute the batch file at a re-occurring time which is convenient for you (5, 10 minutes) – you should ensure that the account that the task context executes in has the correct Exchange permissions

Possible Improvements or future developments for the script

The script itself is very basic – and is designed to give people an idea of what can be accomplished with PowerShell in terms of Exchange Monitoring.

There are a number of improvements that could certainly be made to the overall functionality – the following are a few suggestions that may stimulate the creative minds amongst you:

  • The script determines each Exchange Server from names that are contained within a Text file, there is no reason why this cannot be automated using the Get-ExchangeServer cmdlet and performing role checks based on the “ServerRole” property
  • In the examples given the script uses the actual Exchange Server as the SMTP smart host. In production – it is probably better to use an independent SMTP server, just in case one of the problems that you have is the Exchange Server’s HT function is not working correctly – this will naturally result in no mail being sent
  • There is little or no support for clustered instances (or DAGS) within the script – whereas most of the functions will work against clustered servers – there is no detection of nodes within a cluster or any specific node based tests
  • Some of the script construct is very messy – e.g. the checkDiskSpaceFree function will be called multiple times for multi-role servers resulting in duplicate mails to the admin
  • The HTRoleTest function could be expanded to actually attempt a connection to the HT Server on port 25 – if this fails, the script could failover to another SMTP host
  • The CASRoleTest function does not make use of any commands to test the Autodiscover  or OWA connectivity services – it could be expanded to include these

Summary

This pretty much wraps up this series. In this part we have covered the code that can help you can monitor HT and CAS Servers, provided the completed script and made some suggestions for improvements.

If you would like to read the other parts in this article series please go to:

Andy Grogan

Share
Published by
Andy Grogan

Recent Posts

IFA 2019: All the top smartphone announcements and unveilings

IFA 2019, this year’s version of the annual consumer electronics trade show, did not disappoint. Is one of these smartphones…

49 mins ago

Outlook connectivity: Troubleshooting and solving common issues

IT professionals all dread getting this fevered message from employees and clients: “I’m having Outlook connectivity issues!” Here’s what you…

5 hours ago

Using tags with Azure runbook automation to control your costs

Here’s a script designed to start and stop virtual machines based on tags associated at the resource group level. It…

8 hours ago

Software-defined perimeter solutions: Why this is the future of security

Traditional VPNs are showing their age in the modern cloud-powered workplace. That’s why software-defined perimeter solutions are in your future.

3 days ago

Why you need to check your virtualization host’s NUMA configuration

Should you disallow NUMA spanning in your Hyper-V architecture? There are two sides to this story, and you’ll get both…

3 days ago

Getting started with Visual Studio Code and integrating with Azure DevOps

Coding may not be the No. 1 job duty for cloud admins, but it is often a part of the…

3 days ago