Community MVP hwidjaja dropped a bomb-sized nugget of wisdom in the forums last week that I would be remiss if I didn’t write up and share with the greater community at large.  Zenoss has a WMI executable for linux called wmic, which allows you to query via wmi a windows box.  So in the case for Terminal Services, you can use this tool to check if the TermService service is running, and mark the server up/down appropriately.  Because and external executable with be utilized to do this, and external monitor will be necessary.  Below, I’ll walk you through the steps.

Note: Putting an non-F5 executable on an LTM may negate F5's ability to support the unit, and might require the non-native executables to be removed before assisting in troubleshooting efforts.

Build & Transfer the wmic Executable

The wmic executable isn’t native on LTM, so it is necessary to build it.  I downloaded centOS 5.5 disks 1, 2, & 3 to build a virtual machine for the build.  After the vm is finalized, I followed Hum’s steps here:

Once the build was complete, I switched over to my desktop to pull down the executuble, then transferred it to the LTM:

Next, I moved to the LTM and remounted the /usr file system to read-write so I could dump the executable in /usr/local/bin/:

    • mount –o remount,rw /dev/vg-db-had /usr
    • cp /var/tmp/wmic /usr/local/bin/

Note: You’ll need to check your /etc/fstab for the appropriate location of the /usr file system, it varies.

Testing wmic

Now that I had the executable in place, I tested it from the command line (variables need for script in bold italics):

wmic -U testdom/testaccount%testpasswd //192.168.22.31 "select State from Win32_Service where Name='TermService'”

This resulted in the following output:

CLASS: Win32_Service
Name|State
TermService|Running

Creating the Script

After a successful query via wmi to check the service and the string that shows it’s running (TermService|Running), I created a script (/usr/share/monitors/rdpcheck) for the external monitor to reference:

#!/bin/bash
# remove IPv6/IPv4 compatibility prefix (LTM passes addresses in IPv6 format)
IP=`echo ${1} | sed 's/::ffff://'`
PORT=${2}

PIDFILE="/var/run/`basename ${0}`.${IP}_${PORT}.pid"
# kill of the last instance of this monitor if hung and log current pid
if [ -f $PIDFILE ]
then
kill -9 `cat $PIDFILE` > /dev/null 2>&1
fi
echo "$$" > $PIDFILE

rm -f $PIDFILE

# send request & check for expected response
wmic -U $3/$4%$5 //$IP "select State from Win32_Service where Name='TermService'" | grep -i "TermService|Running" 2>&1 > /dev/null

# mark node UP if expected response was received
if [ $? -eq 0 ]
then
echo "UP"
fi

exit

$1 and $2 are IP and Port with external monitors, and arguments are $3 and beyond.  So in this case, I needed to supply domain, username, & password.  At the command line, this looked like this:

[root@ephesus:Active] monitors # ./rdpcheck ::ffff:192.168.22.31 3389 testdom testaccount testpasswd
UP
[root@ephesus:Active] monitors # ./rdpcheck ::ffff:192.168.22.31 3389 testdom testaccount testpass
NTSTATUS: NT_STATUS_ACCESS_DENIED - Access denied

Deb had a tip a while back when checking external monitors to make sure to supply the ::ffff: ipv6 format with the IPs to make sure the script handles it properly.  Make sure to make the script executable (chmod +x rdpcheck).

Creating the Monitor

Now that the script is working at the command line, it’s time to create the monitor.  Via the command line with bigpipe first, followed by a screenshot of the GUI.

b monitor rdp_mon '{
   defaults from external
   interval 10
   timeout 31
   args "testdom testaccount testpasswd"
   run "/usr/share/monitors/rdpcheck"
}'

 

rdp_mon

That’s it!  Now, assign it to a pool and you’re set:

2010-12-28 16:58:00.053110: ID 53    :(_main_loop): rfd selected [ addr=::ffff:192.168.22.31:3389 srcaddr=98bd:8bbf:921e:6107:98c1:4009:4715:
f08:0 fd=10 pend=0 ]
2010-12-28 16:58:00.053203: ID 53    :(_recv_external_node_ping): reading [ addr=::ffff:192.168.22.31:3389 ]
2010-12-28 16:58:00.053295: ID 53    :(_kill_external_pinger): killing [ addr=::ffff:192.168.22.31:3389 ]
2010-12-28 16:58:00.053893: ID 53    :(recv_external_node_ping): EAV success [ addr=::ffff:192.168.22.31:3389 ]

Conclusion

This tech tip was specifically to show support for the terminal service, but wmic could be used for any other windows service as well, or could be used to ensure a bundle of services are running before considering a server is up.  Standard disclaimers apply, adding things to the file system can cause unexpected results, so test thoroughly.  Also, make sure to back things up as the wmic executable won't survive hotfixes and upgrades. Thanks again to hwidjaja for the excellent resource.