Here is a sanitized version of a Tk app I threw together to monitor sevices on remote Win32 systems and allow me to stop/start them.
Fill in your list of servers and services (or code to build it based on @ARGV, or whatever) where indicated.
@rem = '--*-Perl-*-- @echo off if "%OS%" == "Windows_NT" goto WinNT echo Service control is not supported prior to Windows NT. goto endofperl :WinNT start/min cmd /c "perl -x -S ""%0"" %*" goto endofperl @rem '; #!/usr/bin/perl -w #line 12 use strict; use Tk 8.0 qw( exit ); #qw( Exists Ev exit MainLoop DoOneEvent tkinit +); use Tk::Table; use Tk::Dialog; use Win32::Service qw( GetStatus StartService StopService ); # GUI Objects: my $Window; # The top-level window object my $Table; # The main table my %ColIdx; my $autoRefresh; BEGIN { my @cols= qw( Machine Service Status Since Button ); @ColIdx{@cols}= 0..$#cols; } my @Services; { # Replace this with your own list of servers and services: @Services= ( { Machine => [("Server1")x2], Service => [ "Messenger", "Annoyance Service" ] }, { Machine => [("Server1")x2], Service => [ "lanmanserver", "Backdoor Provider" ] }, { Machine => [("Server2")x2], Service => [ "Browser", "Network Flooder" ] }, ); } exit( main( @ARGV ) ); { my @ServiceState; BEGIN { @ServiceState= ( undef, qw( Stopped *StartING* *StopING* Started *ContinuING* *PausING* Paused ) ); } sub ServiceStatusDisplay { my( $status )= @_; return "*Locked*" if "locked" eq $status; return "*Error*" if "error" eq $status; my $disp= $ServiceState[$status]; return $disp if defined $disp; return $status; } } my( $stopConfirm, $startConfirm ); sub ServiceRefresh { my( $numService, $command )= ( @_, "" ); my $mach= $Services[$numService]{Machine}[0]; my $service= $Services[$numService]{Service}[0]; if( "" ne $command ) { my $resp= ""; if( "start" eq $command ) { $startConfirm ||= $Window->Dialog( -title => "Confirm service start-up", -text => "Proceed?", -buttons => [ qw( Yes No ) ], -default_button => "Yes", ); $startConfirm->configure( -text => "Start the " . $Services[$numService]{Service}[1] . " service o +n " . $Services[$numService]{Machine}[1] . "?", ); $resp= $startConfirm->Show(); } elsif( "stop" eq $command ) { $stopConfirm ||= $Window->Dialog( -title => "Confirm service shutdown", -text => "Are your SURE?", -buttons => [ qw( Yes No ) ], -default_button => "No", ); $stopConfirm->configure( -text => "Are your SURE you want to stop the " . $Services[$numService]{Service}[1] . " service o +n " . $Services[$numService]{Machine}[1] . "?", ); $resp= $stopConfirm->Show(); } elsif( "force" eq $command ) { $Services[$numService]{Service}[0]= $service if $service =~ s/^#// } if( $resp !~ /yes/i ) { ## $Table->put( 1+$numService, $ColIdx{Status}, "Okay" ); return; } } if( "start" eq $command ) { StartService( $mach, $service ) or die "Can't start $service on $mach: $^E\n"; } elsif( "stop" eq $command ) { StopService( $mach, $service ) or die "Can't start $service on $mach: $^E\n"; } else { return if $service =~ /^#/; } my $stats; my $prevStat= $Table->get( 1+$numService, $ColIdx{Status} )->cget( +'-text'); if( ! GetStatus( $mach, $service, $stats= {} ) ) { my $err= $^E; if( $err =~ m#service cannot accept control messages#i || $err =~ m#overlapped i/o operation#i ) { $stats->{CurrentState}= "locked"; } else { $stats->{CurrentState}= "error"; $Services[$numService]{Service}[0]= "#$service"; warn "Can't get status of $service on $mach: $err\n"; } } my $stat= ServiceStatusDisplay( $stats->{CurrentState} ); if( $stat ne $prevStat ) { my @date= (localtime)[4,3,2,1,0]; my $date= sprintf "%02.2d/%02.2d %02.2d:%02.2d:%02.2d", 1+$date[0], @date[1..4]; $Table->get( 1+$numService, $ColIdx{Since} ) ->configure( -text => $date ); } # $Table->put( 1+$numService, $ColIdx{Status}, $stat ); my $button= $Table->get( 1+$numService, $ColIdx{Button} ); my $label= $Table->get( 1+$numService, $ColIdx{Status} ); if( $stat =~ /ING/ || $stat =~ /locked/i || $stat =~ /error/i + ) { $button->configure( -text => "Refresh" ); #-command => sub { ServiceRefresh( $numService, "force" ) +} ); $label->configure( -text => $stat, -bg => 'yellow', -fg => 'black' ); } elsif( $stat eq "Started" ) { $button->configure( -text => "Stop" ); #-command => sub { ServiceRefresh( $numService, "stop" ) } + ); $label->configure( -text => $stat, -bg => 'green', -fg => 'black' ); } else { $button->configure( -text => "Start" ); #-command => sub { ServiceRefresh( $numService, "start" ) +} ); if( $stat eq "Stopped" ) { $label->configure( -text => $stat, -bg => 'red', -fg => 'blue' ); } else { $label->configure( -text => $stat, -bg => 'yellow', -fg => 'black' ); } } $Table->pack() if "nopack" ne $command; } sub ServiceButton { my( $numService )= @_; my $stat= $Table->get( 1+$numService, $ColIdx{Status} )->cget('-te +xt'); if( $stat =~ /ING/ || $stat =~ /locked/i || $stat =~ /error/i + ) { ServiceRefresh( $numService, "force" ); } elsif( $stat eq "Started" ) { ServiceRefresh( $numService, "stop" ); } else { ServiceRefresh( $numService, "start" ); } } sub ServiceRefreshAll { my $next= @_ ? shift(@_) : 0; ServiceRefresh( $next ); if( ++$next < @Services ) { #$Table->after( 100, sub { ServiceRefreshAll($next) } ); $Table->after( 100, [ \&ServiceRefreshAll, $next ] ); } else { $Table->afterCancel( $autoRefresh ) if defined $autoRefresh; $autoRefresh= $Table->after( 15*1000, \&ServiceRefreshAll ) +; } } sub InitWindow { $Window = Tk::MainWindow->new( -title => "NT Services Monitor" ); $Window->Button( -text => "Refresh All", -command => \&ServiceRefreshAll )->p +ack(); $Table= $Window->Table( -rows => 1+@Services, -columns => 5, -fixedrows => 1, -scrollbars => "", -takefocus => 1 ); my @heads= ( "Machine", "Service", "State", "Since", "" ); $Table->put( 0, $_, $heads[$_] ) for 0..$#heads; for my $row ( 0 .. $#Services ) { $Table->put( 1+$row, $ColIdx{Machine}, $Services[$row]{Machine}[1] ); $Table->put( 1+$row, $ColIdx{Service}, $Services[$row]{Service}[1] ); $Table->put( 1+$row, $ColIdx{Status}, "Unknown" ); $Table->put( 1+$row, $ColIdx{Since}, "-" ); my $button= $Table->Button( -text => "Refresh", -command => [ \&ServiceButton, $row ] ); #-command => sub { ServiceRefresh( $row, "force" ) } ); $Table->put( 1+$row, $ColIdx{Button}, $button ); $Services[$row]{UpdateFreq}= 15; } $Table->pack(); } sub main { InitWindow(); $autoRefresh= $Window->after( 200, \&ServiceRefreshAll ); Tk::MainLoop(); return 0; } __END__ :endofperl
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: NtServMon.bat -- monitor, start, and stop remote Win32 services
by TGI (Parson) on Feb 15, 2003 at 04:27 UTC | |
|
Re: NtServMon.bat -- monitor, start, and stop remote Win32 services
by Zanth (Initiate) on Feb 14, 2003 at 18:40 UTC |