http://qs321.pair.com?node_id=75356
Category: NT Admin
Author/Contact Info djw
Description: This program will monitor the following services on a Microsoft Exchange 5.5 server:
  • System Attendant
  • Directory
  • Event Service
  • Information Store
  • Internet Mail Service
  • Message Transfer Agent
  • IIS Admin Service (for OWA)
  • World Wide Web Publishing Service (for OWA)
Although it can be modified to monitor any NT/2k Service.

This script works well when set as a Scheduled Task on a dedicated network monitoring station (mine runs every 2 hours). It will attempt to resume or start any paused or stopped service in your list and report everything it finds in a log file, and will send important notices to an Administrator account or an SMS phone, or pager (requires configuration).

To use SMS or paging services, you will need to setup the send_sms sub to fit your service provider. You could change this to use Net::Pager or SMS, but I found simply using my provider's CGI worked well enough.

Here are some screenshots and example logs here:
Network status log file SMS status log file Let me know if you like this or see anything that could be improved.
ciao,
djw
use Win32::Service;
use Win32::Message;
use HTTP::Request::Common qw(POST);
use URI::URL;
use LWP::UserAgent;

$host = "\\\\servername";
$date = localtime;
$message_type = "pcs";

$recipient = Win32::NodeName();
$sender = Win32::LoginName();
$server = "";

open(FILE, "+>status.txt") || die "Can't clobber file: ($!)\n";
print FILE "==============  $date  ==============\n";

@exchange =
(
    "Microsoft Exchange System Attendant",
    "Microsoft Exchange Directory",
    "Microsoft Exchange Event Service",
    "Microsoft Exchange Information Store",
    "Microsoft Exchange Internet Mail Service",
    "Microsoft Exchange Message Transfer Agent",
    "IIS Admin Service",
    "World Wide Web Publishing Service",
);

%state =
(
    0 => "Unknown",
    1 => "Stopped",
    2 => "Starting",
    3 => "Stopping",
    4 => "Running",
    5 => "Resuming",
    6 => "Pausing",
    7 => "Paused",
);

exchange();

sub exchange
{
    print FILE "========  Exchange Service status on $host   ========\
+n\n";
    foreach $myservice (@exchange)
    {
    getstatus($myservice);
    }
}


sub getstatus
{
    if (Win32::Service::GetServices($host, \%services))
    {
        if ($services{$myservice})
    {
            Win32::Service::GetStatus($host, $services{$myservice}, \%
+status);
        if ($state{$status{CurrentState}} eq "Running")
        {
                write FILE;
        }
        elsif ($state{$status{CurrentState}} eq "Stopped")
        {
                write FILE;
        print FILE "\nWARNING : $myservice is currently Stopped.\n";
        print FILE "Attempting to restart the stopped service....   ";
        send_alert();
        start_service();
        }
        elsif ($state{$status{CurrentState}} eq "Stopping")
        {
        print FILE "\nWARNING : $myservice is attempting to Stop.\n";
        send_alert();
        }
        elsif ($state{$status{CurrentState}} eq "Starting")
        {
        print FILE "\nWARNING : $myservice is attempting to Start.\n";
        send_alert();
        }
        elsif ($state{$status{CurrentState}} eq "Pausing")
        {
        print FILE "\nWARNING : $myservice is attempting to Pause.\n";
        send_alert();
        }
        elsif ($state{$status{CurrentState}} eq "Paused")
        {
        print FILE "\nWARNING : $myservice is currently Paused.\n";
        send_alert();
        resume_service();
        }
        elsif ($state{$status{CurrentState}} eq "Resuming")
        {
        print FILE "\nWARNING : $myservice is Resuming.\n";
        send_alert();
        }
        else
        {
        print FILE "\nWARNING : $myservice is in an Uknown status.\n";
        send_alert();
        }
    }
    else
    {
        print FILE "WARNING : $myservice doesn't exist!\n";
    }
    } 
    else 
    {
    print FILE "Error connecting to $host: ";
    print FILE Win32::FormatMessage(Win32::GetLastError() ), "\n";
    send_alert();
    }
}

print FILE "\n========================================================
+\n";
close(FILE);

sub start_service
{
    if (Win32::Service::StartService($host, $services{$myservice}) )
    {
        print FILE "Success!\n";
    $stat = "Success";
    $attempt = "start";
    send_status($stat, $attempt);
    }
    else
    {
        print FILE "Failed.\n";
    print FILE Win32::FormatMessage(Win32::GetLastError() ), "\n";
    $stat = "Failed";
    $attempt = "start";
    send_status($stat, $attempt);
    }
}

sub resume_service
{
    print FILE "Attempting to resume the $myservice service: ";
    if (Win32::Service::ResumeService($host, $services{$myservice}) )
    {
    print FILE "Success!\n";
    $stat = "Success";
    $attempt = "resume";
    send_status($stat, $resume);
    }
    else
    {
    print FILE "Failed!\n";
    print FILE Win32::FormatMessage(Win32::GetLastError() ), "\n";
    print FILE "Check Event Log for further details.\n";
    $stat = "Failed";
    $attempt = "resume";
    send_status($stat, $resume);
    }  
}

sub send_alert 
{
    if ($message_type eq "net")
    {
            $error = $state{$status{CurrentState}}, "\n";
            $message = "\t\t *** FAILURE STATUS REPORT ***\n\n"
            . "The MS Exchange Service Tool found a problem when monit
+oring $host.\n"
            . "The current state for $myservice is: " . $error . "\n\n
+"
        . "An attempt will be made to restart the $myservice."
        . "\n\n\t\t *****************************\n";
            if (Win32::Message::Send($server, $recipient, $sender, $me
+ssage))
        {
            print FILE "Sent administrative failure message to $recipi
+ent.\n";
        }
        else
        {
            print FILE "The administrative message to $recipient faile
+d.\n";
            print FILE Win32::FormatMessage(Win32::GetLastError() ), "
+\n";
        }
    }
    elsif ($message_type eq "pcs")
    {
        $error = $state{$status{CurrentState}}, "\n";
        $message = "**** FAILURE STATUS REPORT ****\n $myservice is $e
+rror\n.  Attempting to restart\n";
        send_sms($message);
    }
}

sub send_status
{
    if ($message_type eq "net")
    {
        $message =  "\t\t *** SERVICE STATUS REPORT ***\n\n"
        . "Attempting to $attempt service: $myservice\n"
        . "Result: $stat!"
        . "\n\n\t\t ****************************\n";
            if (Win32::Message::Send($server, $recipient, $sender, $me
+ssage))
            {
            print FILE "Sent administrative status message to $recipie
+nt.\n";
            }
            else
            {
            print FILE "The administrative status message to $recipien
+t failed.\n";
            print FILE Win32::FormatMessage(Win32::GetLastError() ), "
+\n";
            }
        }
    elsif ($message_type eq "pcs")
    {
        $message = "**** SERVICE STATUS REPORT ****\n Attempt to $atte
+mpt service $myservice: $stat!";
        send_sms($message);
    }
}

sub send_sms
{
    %form =
    (
        AREA_CODE         => "555",
        PIN1            => "555",
        PIN2            => "5555",
        SENDER            => "5555555555",
        "emapnew--DESC--which"     => "ORIG",
        PAGETEXT1        => "$message",
    );

    $ua = LWP::UserAgent->new();
    $req = url("http://sabre.cantelatt.com/cgi-bin/sendpcs.cgi");
    $req->query_form(%form);

    $response = "";
    $response = $ua->request(HTTP::Request->new('GET', $req));

    $response = $response->{_content};

    if ($response =~ /^\<html\>\<head\>\<title\>Thank You\<\/title\>\<
+\/head\>/)
    {
        print FILE "SMS Administrative message Succeeded\n";
    }
    else
    {
        print FILE "SMS Administrative message Failed\n";
    }
}

format FILE =
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<     @<<<<<<<<<<
$myservice, $state{$status{CurrentState}}
.