cjd143SD
cjd143SD

Reputation: 869

How to select relevant rows in Perl?

I need help altering this Perl code. I can get a list of all services on the host. But, I'm only interested in sending an email message for those services that are Red (stopped). I'm not sure where I set that condition (within the foreach, perhaps)?

Output now:

Service: AeLookupSvc - Green - Auto
Service: Alerter - Red - Disabled
Service: ALG - Red - Manual
Service: AppMgmt - Green - Manual

Perl code:

my @servstat = ("Red","Green");
my $computer = "localhost"; 
my $winsvcs;

my $wmiObj = Win32::OLE->GetObject("winmgmts:\\\\$computer\\root\\CIMV2")
 or die "WMI connection failed.\n";

#get all services
my $servSet = $wmiObj->ExecQuery("SELECT * FROM Win32_Service", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);  

foreach my $serv (in $servSet) { 
     my $sname = $serv->{name};
     my $sstate = $serv->{started};
     my $ssmode = $serv->{startmode};
    $winsvcs .= "Service: " . $sname . " - " . $servstat[$sstate] . " - " . $ssmode . "\n";
 }

Upvotes: 1

Views: 80

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 754050

You can deal with the condition in the SQL query (only return the rows that are relevant - the Red ones). This is probably the best way of dealing with it; it limits the data sent between DBMS and client (which may not matter much on a single machine, or on a LAN connection, but really matters on a WAN connection).

my $servSet = $wmiObj->ExecQuery("SELECT * FROM Win32_Service WHERE Started = 0",
                             "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);  

Alternatively, you can use a test in the for loop so that you add the relevant information to $winsvcs only if the $sstate is 0 (equivalent to Red).

foreach my $serv (in $servSet)
{ 
    next if $serv->{started};
    my $sname  = $serv->{name};
    my $sstate = $serv->{started};
    my $ssmode = $serv->{startmode};
    $winsvcs  .= "Service: $sname - $servstat[$sstate] - $ssmode\n";
}

Note that the . operator can be necessary (particularly if you need to embed the result of a function call), but wasn't really needed in the code you showed. You could even do without the 3 loop variables, but then the line becomes rather long.

    $winsvcs  .= "Service: $serv->{name} - $servstat[$serv->{started}] - $serv->{startmode}\n";

Both methods will work. I recommend modifying the SQL rather than the loop, but the choice is yours.

Upvotes: 2

Related Questions