The need to to monitor arbitrary Powershell scripts comes up now and then and often there are some workarounds or alternatives, NSClient for example, named. However in order to have something I can link refer people to when the topic comes up again, I’ll try to provide a quick and simple to adapt solution. Keep in mind that this assumes you have Icinga 2 up and running on your Windows host, Powershell installed and are reasonably sane.
First the the check script I used for demonstration purposes in this case, all it does is check whether a process is running and returning OK or CRITICAL based on that.
if ($args.Length -lt 1) {
Write-Output "Script requires one argument (Process)"
Exit(3)
}
$proc=$args[0]
$state = Get-Process $proc -ErrorAction SilentlyContinue
if ($state) {
Write-Output "PROCESS OK '$proc' is running"
Exit(0)
} else {
Write-Output "PROCESS CRITICAL '$proc' is not running"
Exit(2)
}
Safe it as check_proccess.ps1 somewhere you can find it again. In this case I put next to the other check plugins.
The following are the check_command object and Service apply. And as it turns out it’s not that easy of a task as I thought, it’s mostly Windows fault really… Getting the exit code of a script from Powershell returned to icinga2 required some trickery (credit goes to NSClient for that one). The result is a bit of weird CheckCommand, which can and should be improved.
object CheckCommand "powershell" {
import "plugin-check-command"
command = [ "cmd" ]
arguments = {
"Weird command" = {
value = "/c echo $powershell_script$ $powershell_args$ ; exit ($$lastexitcode) | powershell.exe -command -"
description = "This is needed because powershell would not tell us the exit code otherwise"
skip_key = true
}
}
}
apply Service "check_powerpoint" {
import "generic-service"
check_command = "powershell"
vars.powershell_script = PluginDir + "\check_process.ps1"
vars.powershell_args = "POWERPNT"
assign where host.vars.os == "Windows"
}


























The above commands works but is not very safe (when the script is not available on the server or has error parsing commands or something).
In the nsclient.ini is used this command:
ps1=cmd /c echo If (-Not (Test-Path „scripts\custom\%SCRIPT%“) ) {write-host „Script not available on server“; exit 3 }; try{ scripts\\custom\\%SCRIPT% %ARGS%} catch {Write-Host $_.Exception.Message; exit 3}; exit($lastexitcode) | powershell.exe -Noninteractive -command –
Which worked very well, but I when I try to adapt this for the Icinga2 command it fails.
I tried:
value = „/c echo If (-Not (Test-Path \“$service.vars.powershell_script$\“) ) {write-host \“Script not available on server\“; exit 3 }; try{ \“$service.vars.powershell_script$\“ $service.vars.powershell_args$} catch {Write-Host $$_.Exception.Message; exit 3}; exit($$lastexitcode) | powershell.exe -Noninteractive -command -“
There might be a better way..
Ignore my previous comment, I would highly recommend using the following CheckCommand:
object CheckCommand „check_win_powershell“{
command = [ „cmd“ ]
arguments = {
„PSCMD“ = {
value = „/c \“powershell If(-Not (Test-Path $powershell_script$) ) {write-host Script not found; exit 3}; try{ $powershell_script$ $powershell_args$ } catch {Write-Host $$_.Exception.Message; exit 3} exit($$lastexitcode)\““
skip_key = true
}
}
}
please add this to the documentation when tested 😉