Thanks for the input. Because of the fact that I started with Perl, I decided to be stubborn and finish in Perl, even though the Sysinternals suite might've made more sense.
Here's what I ended up with:
#!/usr/bin/perl
use v5.14;
use strict;
use warnings;
use DBI;
use Win32::Service;
##
# Hostname of server where this script is being run.
#
my $hostname = `hostname`;
chomp $hostname;
##
# Reference to anonymous array returned by GetStatus.
#
my $w32ServiceStatus = {};
##
# Win32 API service status constants.
#
use constant {
SERVICE_STOPPED => hex('0x00000001'),
SERVICE_START_PENDING => hex('0x00000002'),
SERVICE_STOP_PENDING => hex('0x00000003'),
SERVICE_RUNNING => hex('0x00000004'),
SERVICE_CONTINUE_PENDING => hex('0x00000005'),
SERVICE_PAUSE_PENDING => hex('0x00000006'),
SERVICE_PAUSED => hex('0x00000007'),
};
##
# Additional script constants.
#
use constant {
SLEEP_INTERVAL => 15, # Time to sleep bet
+ween tries (sec.).
MAX_WAIT_TIME => 15, # Max time to wait
+for service to stop (min.).
SERVICE_NAME => 'MY_SERVICE', # Service name.
};
######################################################################
+#
# Get the current status of the service and stop it, if running.
#
Win32::Service::GetStatus('',SERVICE_NAME,$w32ServiceStatus);
if ($w32ServiceStatus->{CurrentState} == SERVICE_RUNNING) {
##
# Process ID.
#
my $pid = -999;
##
# WMI database handle object.
#
my $dbh = DBI->connect('dbi:WMI:');
##
# WMI statement handle object.
#
my $sth = $dbh->prepare(
sprintf ("SELECT * FROM Win32_Service WHERE Name = '%s'",
SERVICE_NAME));
$sth->execute();
if (my $row = $sth->fetchrow()) {
$pid = $row->ProcessID;
}
printf("Attempting to stop %s on $hostname...\n",SERVICE_NAME);
##################################################################
+#
# Stop the service.
#
Win32::Service::StopService('',SERVICE_NAME)
or die sprintf("Unable to stop %s on %s: %s\n",
SERVICE_NAME,$hostname,$!);
printf("%s on %s stopping.\n",SERVICE_NAME,$hostname);
##################################################################
+#
# Continue to wait until the process is fully stopped.
#
my $stopCount = 0;
while ($pid > 0 && $stopCount < (60 / SLEEP_INTERVAL * MAX_WAIT_TI
+ME)) {
sleep SLEEP_INTERVAL;
$sth->execute();
if (my $row = $sth->fetchrow()) {
$pid = $row->ProcessID;
}
$stopCount++;
}
##################################################################
+#
# If the time taken to stop exceeds the maximum wait time, then
# error out.
#
if ($stopCount < (60 / SLEEP_INTERVAL * MAX_WAIT_TIME)) {
printf("%s stopped on %s.\n",SERVICE_NAME,$hostname);
} else {
die sprintf("Unable to stop %s on %s: %s\n",
SERVICE_NAME,$hostname,$!);
}
}
######################################################################
+#
# Service is not running.
#
else {
printf("%s is not currently running on %s.\n",SERVICE_NAME,$hostna
+me);
}
######################################################################
+#
# ...do whatever we're going to do before restarting the service...
#
######################################################################
+#
# Restart the service, if it was running to start with.
#
if ($w32ServiceStatus->{CurrentState} == SERVICE_RUNNING) {
printf("Attempting to start %s on %s.\n",SERVICE_NAME,$hostname);
Win32::Service::StartService('',SERVICE_NAME)
or die sprintf("Unable to start %s on %s.\n",SERVICE_NAME,
+$hostname);
printf("%s on %s started.\n",SERVICE_NAME,$hostname);
}
JAPG (Just Another Perl Grasshopper)
|