# SvcNanny 1.0 # # This script checks the specified list of services on specified servers # and restarts those that crashed. # # It's meant to be used as a service but may be used from command line as well of course. # You need srvany.exe from the resource kit if you want to use it as a service : # # copy the srvany.exe somewhere (say c:\tools) # run: INSTSRV SvcNanny C:\TOOLS\srvany.exe # configure the service via the Control panel\Services # automatic/manual startup, account, ... # Run the Registry Editor (REGEDT32.EXE): # under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService: create a 'Parameters' key # under the above key, create an 'Application' value of type REG_SZ and # specify there the full path to perl.exe. For example: # Application: REG_SZ: C:\perl\bin\perl.exe # under the above key, create an 'AppParameters' value of type REG_SZ and # specify there the FULL path to this script plus all parameters (timeout and services) # For Example: # AppParameters: REG_SZ: C:\TOOLS\SvcNanny.pl 600 Spooler Spooler@OtherSrv "World Wide Web Publishing Service" # # by Jenda@Krynicky.cz http://Jenda.Krynicky.cz $version = 1.0; use Win32::Service qw(GetStatus StartService); use Win32::Registry; if ($ARGV[0] eq $ARGV[0]+0) { $timeout = shift @ARGV; } else { $timeout = 600; } if ($ARGV[-1] =~ /^-(.*)$/) { my $file = $1; print "Printing into log file : $file\n"; open LOG, '>>'.$file or die "Cannot open the log file : $!\n"; select LOG;$|=1; pop @ARGV; } die "Ussage: svcnanny [timeout] ServiceName [ServiceName\@ServerName ...] [-LogFile] This script checks the status of specified services on specified servers and restarts any service that stops. \ttimeout = the delay between tests in seconds \tServiceName = either the display name (the name you see in Services \t\tControl panel) or the name of the service's key in registry \t\@ServerName = a name of the server on which the script should foster \t\tthe service \t\t-LogFile = the path to the log file preceded by a dash! " unless @ARGV; print scalar(localtime)," STARTING\n"; foreach $item (@ARGV) { if ($item =~ /^(.*)@(.*?)$/) { $server = $2; $service = $1; $handle = Win32::Registry::Open("\\\\$server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services"); unless ($handle) { print "Cannot connect server \\\\$server : $^E\nSkipping $item\n\n"; next; } } else { $server = ''; $service = $item; $handle = $HKLM->Open('SYSTEM\CurrentControlSet\Services') } if ($handle->Open($service)) { push @services, [ ($server ? "$service\@$server" : $service) , $service => $server]; } else { my $found; foreach $key ($handle->GetKeys()) { my $name; eval { $name = $handle->Open($key)->GetValue('DisplayName') }; if ($name eq $service) { push @services, [ ($server ? "$service\@$server" : $service), $key => $server]; $found = 1; last; } } print( "Service '$service' not found on ", $server ? "\\\\$server\n\n" : "local machine!\n\n") unless $found; } } die "No services to look after!!!\n" unless @services; while(1) { print scalar(localtime),"\n"; foreach $item (@services) { ($name, $service, $server) = @$item; GetStatus($server,$service,\%status); unless ($status{CurrentState} == 4) { print "\t$name : Oops, it's down!!! Restarting ... "; StartService($server, $service) and print "OK\n" or print "FAILED!!!\n"; } else { print "\t$name : OKAY\n"; } } sleep($timeout); }