Hello
I am new in icinga / nagios world. Found that Linux is very rich in plugin- but scripts around windows are hard to find by. I have done monitoring with different tools for many years. I have seen how dynamic the requirement comes to monitor Windows Service. In one server, X-service in another server, Y-service and then in other server all services.
I have always had good results with running with the formula
Status !=running and Startup = "auto" and exit code !=0
The above type formula monitors all service by default which is in automatic startup.
Then we also get requirement to exclude few services which we do not need to alert in case it is down.
Then we also get requirement to monitor only specific services.
To cater all that I came up with the below powershell script. I actually do not know how to use it in icinga2 and I need help on that. Also I need feedback or bug checks by all the experts out here. Please understand this is my first powershell script so don’t get hard on me
What I am trying to make is one plugin which should be able to cater to all windows service monitoring requirement. Again if there is already a plugin like this available please share so that I can use it myself as well. Please share feedback and help in using this in icinga2
Run the script in Powershell ->
#C:\Users\Documents\icinga2\Plugins\Windows\TestService.ps1 -crit|warn 1 -excludeService "A,B,C,D" -startMode "auto|manual" -exitCode 0|1
#C:\Users\Documents\icinga2\Plugins\Windows\TestService.ps1 -crit|-warn 1 -includeService "A,B,C,D" -exitCode 1|0
# Checks either Group of Service as mentioned in argument includeService Or All Service. By default it is all Service
# Obviously you cannot monitor all services as well as group of services - so either you keep allService to blank or 0 and fill includeService OR make allService to 1 and keep includeService to blank
# By Default it checks all service which is in auto startup
# Comma Separated Exclusion List of Service when you monitor all service
# List of Argument being Passed from Icinga2
#Service exitCode : Blank is considered as 0
param([string]$servername, [string]$excludeService, [string]$includeService, [string]$startMode, [string]$state, [int]$exitCode, [int]$allService, [int]$warn, [int]$crit)
$singlequote = "'" #Hammering the command as double quote and single quote is confused in the cim command:P
if (!$state){
# Defaulting state to running for all services
$state = "running"
}
if (!$startMode){
#Defaulting start mode to auto for all service so that we can monitor by default all automatic services only when it is monitoring AllService
$startMode = "auto"
}
if ($exitCode){
# Defaulting exit code
if ($exitCode -ge 2){
write-host "Unknown: The exitCode can be blank or 0 or 1"
exit 3;
}
}
if (!$includeService -and !$allService){
#neither includeService is mentioned nor allService is mentioned defaulting to all service
$allService = 1
}
if (!$warn -and !$crit){
#neither warn is mentioned nor crit is mentioned defaulting to all service
$warn = 1
}
if ($allService){
# Defaulting allSerivce code
if ($allService -ge 2){
write-host "Unknown: The allService can be blank or 0 or 1"
exit 3;
}
}
if ($excludeService){
#we expect comma separated services
$arr = $excludeService -split ','
foreach ($xelement in $arr){
$excludeServiceString = $excludeServiceString + ' and ' + 'name !=' + '"' + $xelement+ '"'
}
}
if ($includeService){
#we expect comma separated services
$arr = $includeService -split ','
foreach ($ielement in $arr){
$includeServiceString = $includeServiceString + ' or ' + 'name =' + '"' + $ielement+ '"'
}
#we need to replace the first occurance of or to and
$includeServiceString = $includeServiceString -replace '(.*?)or(.*)', '$1and$2'
echo $includeServiceString
}
if ($allService -eq 1 -and $includeService){
# Defaulting allSerivce code
write-host "Unknown: Ambiguous request. Either You want to monitor All Service Or Specified Service in include Service"
exit 3;
}
if ($includeService -and $excludeService){
# Defaulting allSerivce code
write-host "Unknown: Ambiguous request. Either You want to include Service or exclude Service"
exit 3;
}
if ($allService){
#We want to include all Service
if ($startMode){
#We want to include startMode
if ($state){
#We want to include state (ideally should monitor not equal to running)
if ($exitCode -eq 0){
#Exit code is 0
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'startmode = "'+$startMode+'" and state != "'+$state+'" and exitcode ='+$exitCode+' '+$excludeServiceString+''+$singlequote+').displayname'
}
else{
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'startmode = "'+$startMode+'" and state != "'+$state+'" and exitcode !=0 '+$excludeServiceString+''+$singlequote+').displayname'
}
}
else{
write-host "Unknown: The state is messed up. It should be set as 'running'"
exit 3
}
}
else {
#I do not have a start mode mapping
if ($exitCode -eq 0){
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'state != "'+$state+'" and exitcode ='+$exitCode+' '+$excludeServiceString+''+$singlequote+').displayname'
}
else{
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'state != "'+$state+'" and exitcode !=0' +$excludeServiceString+''+$singlequote+').displayname'
}
}
}
else {
#-----------------TO DO ---------------------------#
#Looks like we want to monitor only the specific services in include service
if ($exitCode -eq 0){
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'state != "'+$state+'" and exitcode ='+$exitCode+' '+$includeServiceString+' '+$excludeServiceString+''+$singlequote+').displayname'
}
else{
$query = '(Get-CimInstance win32_service -Filter '+$singlequote+'state != "'+$state+'" and exitcode !=0' +$excludeServiceString+'' +$includeServiceString+ ''+$singlequote+').displayname'
}
}
try{
#echo $query
$serviceStatus = Invoke-Expression $query
}
catch{
Write-Output $_;
$_="";
exit 3;
}
if (!$serviceStatus){
#No Service Returned matching the query means all good
Write-Host "OK: All services are up and running"
exit 0;
}
elseif ($serviceStatus -and $warn){
Write-Host "WARNING: $serviceStatus are in $startMode and is currently in stopped state"
exit 1;
}
else{
Write-Host "CRITICAL: $serviceStatus are in $startMode and is currently in stopped state"
exit 2;
}