Seite wählen

Monitoring Powershell scripts with Icinga 2

von | Apr 27, 2017 | Windows, Icinga, Monitoring & Observability, Betriebssysteme


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"
}

3 Kommentare

  1. Andrew Shewchenko

    It should also be noted that spaces in the path really mess it up too. PluginDir in Windows is often some variation of C:\Program Files\ICINGA2\sbin , which means you need to encapsulate the path so it’s treated as one entity…. which means echo actually only echoes out the path of the script because it’s treated as a string literal for some reason….
    We’ve had the best luck putting our powershell scripts in c:\scripts (and using the hacky command you’ve given us!) so space-escaping and other Windows shenanigans don’t get in our way.

    Antworten
  2. Duffkess

    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..

    Antworten
    • Duffkess

      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 😉

      Antworten

Einen Kommentar abschicken

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Herausforderungen beim Prometheus Scaling

Prometheus ist eine ausgezeichnete Monitoring-Lösung, wenn es um die Überwachung von Verfügbarkeit und Performance geht. Das initiale Deployment geht schnell und mit ein bisschen PromQL KnowHow hat man die Dashboards und Alarme schnell am Laufen. Schon steht die...