<?xml version="1.0" encoding="windows-1252"?>
<node id="963303" title="Auto-Restarting Windows Services" created="2012-04-03 15:55:52" updated="2012-04-03 15:55:52">
<type id="1042">
CUFP</type>
<author id="961961">
temporal</author>
<data>
<field name="doctext">
&lt;p&gt;Greetings fellow monks.&lt;/p&gt;

&lt;p&gt;I recently had to throw together a script which would kick-start a Windows service (scheduler).&lt;/p&gt;

&lt;p&gt;This was due to a particularly overzealous IT department's user group policy disabling user-initiated services at seemingly random intervals.&lt;/p&gt;

&lt;p&gt;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:&lt;/p&gt;

&lt;code&gt;# /usr/bin/perl
# child process to background
# poll windows service (scheduler) and re-enable + start

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, '&gt;&gt;', $logfile);
		print LOG currtime() . "\tscheduler stop detected, restarted the service\n";
		close LOG;
	}
	sleep(60);
}

# culled/tweaked 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 $_ =&gt; $_) } ('Boot', 'System', 'Automatic',
	                                           'Manual', 'Disabled');
	
	(exists $types{$type})
	    or die '&lt;type&gt; must be one of ', join ' ', keys %types;
	
	# Bomb out completely if COM engine encounters any trouble.
	Win32::OLE-&gt;Option ('Warn' =&gt; 3);
	
	# Get a handle to the SWbemServices object of the local machine.
	my $computer = Win32::OLE-&gt;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-&gt;InstancesOf ('Win32_Service');
	
	# Convert set to a Perl array.
	my @services = Win32::OLE::Enum-&gt;All ($services_set);
	
	foreach my $service (@services) {
	    my $name = $service-&gt;{'Name'};
	    my $display_name = $service-&gt;{'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-&gt;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);
}&lt;/code&gt;

&lt;p&gt;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!&lt;/p&gt;</field>
</data>
</node>
