# SC.PL
#
# Reports the state of a service and its startup option
# Stops, Starts or restarts a service
# Changes the startup option of a service
#
# This script was written by Paul Popour (ppopour@infoave.net) in 09/2000.
# It is released into the public domain. You may use it freely, however,
# if you make any modifications and redistribute, please list your name
# and describe the changes. This script is distributed without any warranty,
# express or implied.
#
# SYNTAX - perl sc.pl {-server [servername]} {-service [servicename]} {-action [action]}
#
# Examples
#
# perl sc.pl -server SERVER1 -service WINS
#
# Show the status of the Wins service on SERVER1
#
# perl sc.pl -server SERVER1 -service WINS -action RESTART
#
# Stops then starts the Wins service on SERVER1
#
# perl sc.pl -server SERVER1
#
# Displays all services on SERVER1
#
# This script is used to control services on remote servers
#
# This script requires the Win32::Lanman module available at the
# following sites:
#
# http://jenda.mccann.cz/
# http://www.roth.net/perl/
#
# Thanks to Jens Helberg for this excellent module.
#
#
use Getopt::Long;
use Win32::Lanman;
GetOptions ('server:s', \$server, 'service:s', \$service, 'action:s', \$action);
if ((@ARGV[0] eq "help") || (@ARGV[0] eq "?")){&syntax; exit 1;}
if ($server eq ""){$server = $ENV{COMPUTERNAME};}
if ($action ne ""){$action = "\U$action\E";}
%commands = ('STOP' => 1,'START' => 1,'RESTART' => 1,'AUTOMATIC' => 1,'MANUAL' => 1,'DISABLED' => 1);
if (($action ne "")&&($commands{$action} != 1))
{
print "\n\nInvalid command - $action\n\n";
&syntax;
exit 1;
}
%status = ( 1 => 'Stopped', 2 => 'Start Pending',
3 => 'Stop Pending', 4 => 'Running',
5 => 'Continue Pending',6 => 'Pause Pending',
7 => 'Paused');
%start = (2 => 'Automatically', 3 => 'Manually', 4 => 'Disabled');
%startup = (AUTOMATIC => '2', MANUAL => '3', DISABLED => '4');
if(!Win32::Lanman::EnumServicesStatus("\\\\$server", "", &SERVICE_WIN32, &SERVICE_STATE_ALL, \@services))
{
print "\n\nCannot read services information on $server\n\n";
&syntax;
exit 1;
}
foreach (@services)
{
$state{${$_}{'name'}} = ${$_}{'state'};
if ("\U${$_}{'name'}\E" eq "\U$service\E")
{
$service = ${$_}{'name'};
$sn = 1;
last;
}
elsif (${$_}{'display'} =~ /$service/i)
{
@mightbe = (@mightbe, "${$_}{'name'}");
}
}
if (($sn != 1)&&(@mightbe < 1))
{
foreach (@services){print "${$_}{'name'} = ${$_}{'display'}\n";}
print "\nUnable to locate $service service\n";
exit 1;
}
if (($sn == 1)&&($action eq ""))
{
if(!Win32::Lanman::QueryServiceConfig("\\\\$server", '', "$service", \%config))
{
print "Can't query config of $service on $server " . Win32::Lanman::GetLastError() . "\n";
}
print "$service ($config{'display'}) is $status{($state{$service})} and set to start ${start{$config{'start'}}}\n";
exit 1;
}
if (($sn == 1)&&($commands{$action} == 1))
{
&$action;
exit 1;
}
if ((@mightbe == 1)&&($action eq ""))
{
$service = $mightbe[0];
if(!Win32::Lanman::QueryServiceConfig("\\\\$server", '', "$service", \%config))
{
print "Can't query config of $service on $server " . Win32::Lanman::GetLastError() . "\n";
}
print "$service ($config{'display'}) is $status{($state{$service})} and set to start ${start{$config{'start'}}}\n";
exit 1;
}
if ((@mightbe == 1)&&($commands{$action} == 1))
{
$service = $mightbe[0];
if(!Win32::Lanman::QueryServiceConfig("\\\\$server", '', "$service", \%config))
{
print "Can't query config of $service on $server " . Win32::Lanman::GetLastError() . "\n";
}
print "$service ($config{'display'}) is $status{($state{$service})} and set to start ${start{$config{'start'}}}\n";
if ("\U${start{$config{'start'}}}\E" eq $action)
{
print "Startup is already ${start{$config{'start'}}} - No change needed\n";
exit 1;
}
&$action;
exit 1;
}
if (@mightbe > 1)
{
print "\n\n\n";
$mbcount = 1;
foreach (@mightbe)
{
print "$mbcount - $mightbe[$mbcount-1] -";
foreach (@services)
{
if (${$_}{'name'} eq $mightbe[$mbcount-1])
{
print " ${$_}{'display'} ($status{$state{${$_}{'name'}}})\n";
}
}
$mbcount++;
}
until (($trash > 0)&&($trash <= @mightbe))
{
print "\n\nPlease select the service (Ctrl/C to abort)\n\n";
$trash = <STDIN>;
chomp $trash;
}
$trash = $trash -1;
$service = $mightbe[$trash];
if(!Win32::Lanman::QueryServiceConfig("\\\\$server", '', "$service", \%config))
{
print "Can't query config of $service on $server " . Win32::Lanman::GetLastError() . "\n";
}
if ($action eq "")
{
print "$service ($config{'display'}) is $status{($state{$service})} and set to start ${start{$config{'start'}}}\n";
exit 1;
}
else
{
if ("\U${start{$config{'start'}}}\E" eq $action)
{
print "Startup is already ${start{$config{'start'}}} - No change needed\n";
exit 1;
}
&$action;
exit 1;
}
}
sub syntax
{
print "\n\nSYNTAX:\n\nperl sc.pl -server [servername] -service [servicename] -action [action]";
print "\n\n\nEXAMPLES:\n\nperl sc.pl -server server1 -service spooler -action restart";
print "\n\n\tStops the starts the Spooler service on Server1";
print "\n\nperl sc.pl -server server1 -service spooler ";
print "\n\n\tDisplays the current status of the Spooler service on Server1";
print "\n\n\tPossible actions - stop, start, restart, automatic, manual, disabled\n\n";
}
sub STOP
{
if ($state{$service} != 4)
{
if ($action eq "RESTART"){return();}
print "\n\n$service currently state is $status{($state{$service})} - Cannot stop\n\n";
exit 0;
}
if(!Win32::Lanman::StopService("\\\\$server", '', "$service", \%H1))
{
&cstate;
print "\n\nError stopping $service service on $server\n\nCurrent state is $status{$state}\n";
exit 0;
}
sleep(2);
&cstate;
$count = 0;
until (($state == 1)||($count == 20))
{
sleep(1);
&cstate;
$count++;
}
if (($state != 1)&&($count == 20))
{
print "\n\nError stopping $service service on $server\n\nCurrent state is $status{$state}\n";
exit 1;
}
print "$service service on $server is $status{$state}\n";
}
sub START
{
if(!Win32::Lanman::StartService("\\\\$server", '', "$service"))
{
print "\n\nError starting $service service on $server\n\n";
exit 0;
}
sleep(2);
&cstate;
$count = 0;
until (($state == 4)||($count == 20))
{
sleep(1);
&cstate;
$count++;
}
if (($state != 4)&&($count == 20))
{
print "\n\nError starting $service service on $server\n\nCurrent state is $status{$state}\n";
exit 1;
}
print "$service service on $server is $status{$state}\n";
}
sub RESTART
{
&STOP;
&START;
}
sub AUTOMATIC
{
&CHANGE;
}
sub MANUAL
{
&CHANGE;
}
sub DISABLED
{
&CHANGE;
}
sub CHANGE
{
print "Modifying startup parameter of $service on $server\n";
if (!Win32::Lanman::ChangeServiceConfig("$server", "" ,"$service", {start => "$startup{$action}"}))
{
print "Unable to update the $service service configuration on $server\n";
return;
}
if(!Win32::Lanman::QueryServiceConfig("\\\\$server", '', "$service", \%config))
{
print "Can't query config of $service on $server " . Win32::Lanman::GetLastError() . "\n";
}
print "$service is $status{($state{$service})} and set to start ${start{$config{'start'}}}\n";
exit 1;
}
sub cstate
{
if(!Win32::Lanman::EnumServicesStatus("\\\\$server", "", &SERVICE_WIN32, &SERVICE_STATE_ALL, \@services))
{
print "\n\nCannot read services information on $server\n\n";
exit 0;
}
foreach (@services)
{
if (${$_}{'name'} eq $service)
{
$state = ${$_}{'state'};
}
}
}