Skip to content

Instantly share code, notes, and snippets.

@mshock
Created May 15, 2012 14:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mshock/2702379 to your computer and use it in GitHub Desktop.
Save mshock/2702379 to your computer and use it in GitHub Desktop.
restart Windows services
# /usr/bin/perl
# child process to background
# poll windows services and re-enable + start them
use Win32::Service;
use Win32::OLE;
use strict;
# set logfile location
my $logfile = 'log.txt';
my ($key, %service, %status);
while (1) {
Win32::Service::GetStatus('','Schedule', \%status);
if (!($status{CurrentState} == 4)) {
# service probably disabled, set to automatic again
set_starttype('automatic','schedule');
Win32::Service::StartService('', 'Schedule') || die "could not start service: $!\n";
open(LOG, '>>', $logfile);
print LOG currtime() . "\tscheduler stop detected, restarted the service\n";
close LOG;
}
sleep(300);
}
# culled from: http://unattended.sourceforge.net/
sub set_starttype {
my ($type, $service_name) = @_;
# Convert to lower-case
$type = lc $type;
$service_name = lc $service_name;
my %types = map { (lc $_ => $_) } ('Boot', 'System', 'Automatic',
'Manual', 'Disabled');
(exists $types{$type})
or die '<type> must be one of ', join ' ', keys %types;
# Bomb out completely if COM engine encounters any trouble.
Win32::OLE->Option ('Warn' => 3);
# Get a handle to the SWbemServices object of the local machine.
my $computer = Win32::OLE->GetObject ('WinMgmts:');
# Get the SWbemObjectSet of all services. See:
# http://msdn.microsoft.com/library/en-us/wmisdk/wmi/win32_service.asp
my $services_set = $computer->InstancesOf ('Win32_Service');
# Convert set to a Perl array.
my @services = Win32::OLE::Enum->All ($services_set);
foreach my $service (@services) {
my $name = $service->{'Name'};
my $display_name = $service->{'DisplayName'};
if (($service_name eq lc $name)
|| ($service_name eq lc $display_name)) {
print "Setting mode for $name ($display_name) to $types{$type}...";
my $ret = $service->ChangeStartMode ($types{$type});
$ret == 0
or die "Unable to ChangeStartMode to $types{$type}: $ret";
print "done.\n";
}
}
}
sub currtime {
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
return sprintf("[%02u/%02u/%u %02u:%02u:%02u]", $mon + 1, $mday, $year + 1900, $hour, $min, $sec);
}
@mshock
Copy link
Author

mshock commented May 15, 2012

I recently had to throw together a script which would kick-start a Windows service (scheduler).

This was due to a particularly overzealous IT department's user group policy disabling user-initiated services at seemingly random intervals.

Of course I'm too lazy to write timing into my all of my scripts. And I'm yearning for cron-like functionality. So here's what I put together.

Fork+exec it into the background and it's smooth sailing. Should note that polling frequency should be less than script frequency. I hope that someone will find it useful!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment