I was recently asked to develop health monitors on my 10.2.4HF3 LTMs for our Exchange 2010 environment. Two of the three monitors were a bit challenging, so I wanted to share what I developed.  The monitors have been sanitized to protect our environment - modify them to fit yours.

*** Active Sync ***

This monitor was challenging me, until I stumbled across this statement for versions 10.2.x and 11.x in SOL2167:
"When Basic Authentication is enabled by configuring a User Name and Password in the monitor definition, the system inserts the Authorization header and a terminating double CR/LF sequence (0x0d 0x0a 0x0d 0x0a) after the last character in the Send String."

Once I read that, I removed my standard trailing "\r\n\r\n" sequence at the end of the Send String, and the monitor immediately started working. It saved me from having to use an External monitor. You will need to insert a username, password, and host header value in the send string to fit your environment:
 

   1: ltm monitor https active-sync {
   2: cipherlist "DEFAULT:+SHA:+3DES:+kEDH"
   3: compatibility "enabled"
   4: defaults-from https
   5: interval 10
   6: password "<password>"
   7: recv "MS-ASProtocolCommands: Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteCollection,MoveCollection,FolderSync"
   8: send "OPTIONS /Microsoft-Server-ActiveSync/ HTTP/1.1\r\nHost: <host header value>"
   9: time-until-up 0
  10: timeout 31
  11: username "<domain>\<username>"
  12: }

*** Outlook Web Access ***

This monitor was straightforward. You will need to replace the FQDN in both the URI and the Host: header in the Send String:
 

   1: ltm monitor https outlook-web-access {
   2: cipherlist "DEFAULT:+SHA:+3DES:+kEDH"
   3: compatibility "enabled"
   4: defaults-from https
   5: interval 10
   6: recv "OutlookSession="
   7: send "GET /owa/auth/logon.aspx?url=https://<hostname>/owa/&reason=0 HTTP/1.1\r\nUser-Agent: Mozilla/4.0\r\nHost: <hostname>\r\n\r\n"
   8: time-until-up 0
   9: timeout 31
  10: }

*** Outlook Anywhere ***

This monitor was complicated enough that it could not be done by any of the built-in monitor types, so I had to run this with CURL as an External monitor. Here is the LTM monitor definition:
 

   1: ltm monitor external outlook-anywhere {
   2: defaults-from external
   3: interval 10
   4: run "outlook-anywhere.sh"
   5: time-until-up 0
   6: timeout 31
   7: user-defined debug "0"
   8: user-defined debugfile "/shared/tmp/outloo-anywhere_debug.log"
   9: user-defined receivestring "200 Success"
  10: user-defined username "<domain>\<username>"
  11: }


In order to get this monitor to run in your environment you must update the username variable. In our environment, I had to precede the username with our domain name in order for it to return successful. The outlook-anywhere.sh script looks like this. It needs to be placed in /config/monitors with execute permission:

   1: #!/bin/bash
   2: #
   3: # Exchange 2010 Outlook Anywhere external health monitor
   4: #
   5: # Syntax: /config/monitors/outlook-anywhere.sh
   6: #
   7: # Author:
   8: # Date:
   9: #
  10: # Important Notes:
  11: # * Username must be preceded by the "<domain>\" string
  12: # * There should be four Variables configured in the monitor properties:
  13: # - USERNAME: the user credentials used to perform the check
  14: # - RECEIVESTRING: The string to look for in a successful response
  15: # - DEBUG: Enables output debugging
  16: # - DEBUGFILE: File which tores debug output (if DEBUG is enabled)
  17: # * The password for USERNAME should only be stored in this file. This way,
  18: # it is not accessible via TMSH commands or by viewing the LTM config file
  19: # * To execute this script manually, uncomment the variables and execute
  20: # the shell script. The output will be stored in DEBUGFILE.
  21: # * CAUTION: If you execute this script manually, Make sure you comment
  22: # the USERNAME, RECEIVESTRING, DEBUG, and DEBUGFILE variables (do not
  23: # commend the PASSWORD variable). If you do not comment these variables,
  24: # they will override the variables configured in the Monitor properties
  25: #
  26: # Revisions:
  27: #
  28:  
  29: # Do not comment out the PASSWORD variable
  30: PASSWORD='<password>'
  31:  
  32: # Uncomment these variables temporarily if you want to execute the
  33: # script manually
  34: #USERNAME='\'
  35: #RECEIVESTRING='200 Success'
  36: #DEBUG=1
  37: #DEBUGFILE=/shared/tmp/outlook-anywhere_debug.log
  38:  
  39: # Remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format)
  40: IP=`echo ${1} | sed 's/::ffff://'`
  41: PORT=${2}
  42:  
  43: # Create a PID file
  44: PIDFILE="/var/run/`basename ${0}`.${IP}_${PORT}.pid"
  45:  
  46: # Kill of the last instance of this monitor if hung and log current pid
  47: if [ -f $PIDFILE ]
  48: then
  49: kill -9 `cat $PIDFILE` >; /dev/null 2>&1
  50: fi
  51: echo "$$" >; $PIDFILE
  52:  
  53:  
  54: if [ $DEBUG -eq 0 ]
  55: then
  56:  
  57: curl -v -k --request RPC_IN_DATA -A MSRPC -u "${USERNAME}:${PASSWORD}" --ntlm -H "Host: <hostname>" "https://${IP}/rpc/rpcproxy.dll?:6001" 2>;&1 | grep -ic "${RECEIVESTRING}" > /dev/null 2>&1
  58:  
  59: else
  60:  
  61: echo "*******************" 2>;&1 > "${DEBUGFILE}"
  62: echo -e "curl -v -k --request RPC_IN_DATA -A MSRPC -u '${USERNAME}:${PASSWORD}' --ntlm -H \"Host: <hostname>\" \"https://${IP}/rpc/rpcproxy.dll?:6001\" 2>&1 | grep '200 Success'\n" 2>;&1 >> "${DEBUGFILE}"
  63: echo "USERNAME: ${USERNAME}" 2>;&1 >> "${DEBUGFILE}"
  64: echo "PASSWORD: ${PASSWORD}" 2>;&1 >> "${DEBUGFILE}"
  65: echo "RECEIVESTRING: ${RECEIVESTRING}" 2>;&1 >> "${DEBUGFILE}"
  66: echo "DEBUG: ${DEBUG}" 2>;&1 >> "${DEBUGFILE}"
  67: echo "DEBUGFILE: ${DEBUGFILE}" 2>;&1 >> "${DEBUGFILE}"
  68: echo -e "*******************\n" 2>;&1 >> "${DEBUGFILE}"
  69:  
  70: curl -v -k --request RPC_IN_DATA -A MSRPC -u "${USERNAME}:${PASSWORD}" --ntlm -H "Host: <hostname>" "https://${IP}/rpc/rpcproxy.dll?:6001" 2>;&1 | tee -a "${DEBUGFILE}" | grep -ic "${RECEIVESTRING}" > /dev/null 2>&1
  71: fi
  72:  
  73: # Retain the return code of the grep command.
  74: EXITCODE=$?
  75:  
  76: # Need to remove PIDFILE here because the LTM terminates the script after
  77: # receiving anythin in STDOUT
  78: rm -f $PIDFILE
  79:  
  80: if [ $EXITCODE -eq 0 ]
  81: then
  82: echo "UP"
  83: fi

 

 

  • In order to get this script to run in your environment you must update the PASSWORD variable, and insert your <hostname> into Host: header and the URI string in all three CURL command references.
  • To execute the script manually, you must define the variables that are normally passed by the LTM by uncommenting them near the top of the script. If you do uncomment these variables, make sure you comment them out when you are finished or they will override the variables in the Monitor definition:

                      USERNAME

                      RECEIVESTRING

                      DEBUG (if desired)

                      DEBUGFILE (if DEBUG desired)