Schedule downtime using PowerShell returns a 500 Internal Server Error

@weust i developed a script to send passive check results based on your downtime script.
The script takes these parameters:

-hostname (optional)
-servicename (required)
-plugin_output (required)
-exit_status (required)
-perfdata (optional)
-ttl (optional)

See the documentation for details about the parameters.

param (
	[string]$hostname = ${env:COMPUTERNAME}.ToLower(), 
	[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
	[string]$servicename = $(throw "-servicename is required."),   
	[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
	[string]$plugin_output = $(throw "-plugin_output is required."),
	[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
	[string]$exit_status = $(throw "-exit_status is required."),
	[string]$perfdata,
	[int]$addtottl = 0
)

$versionMinimum = [Version]'4.0'
if ($versionMinimum -gt $PSVersionTable.PSVersion) { 
	Write-Host "This script requires PowerShell $versionMinimum" 
	exit 4
}

# Variables
$icingaHost = "<ICINGAHOST FQDN>"
$apiPort = 5665
$apiUser = "<APIUSER>"
$apiPassword = "<APIPASSWORD>"

if ($addtottl -gt 0) {
	$ttl = [int][double]::Parse((Get-Date (Get-Date).AddHours($addtottl) -UFormat %s))
}	

# Authentication
$pair = "${apiUser}:${apiPassword}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"

# check if service exists on given host
# Icinga stuff
$Uri = "https://" + $icingaHost + ":" + $apiPort + "/v1/objects/services"
$headers = @{ "Authorization" = "$basicAuthValue"; "Accept" = "application/json"; "X-HTTP-Method-Override" = "GET"}
$body = @{
    filter          = 'host.name=="' + $hostname + '" && service.name=="' + $servicename + '"'
}
$body = $body | ConvertTo-Json
# Ignore self signed certificates
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

# Schedule the downtime
$response = Invoke-RestMethod -Headers $headers -Uri $Uri -Method Post -ContentType 'application/json' -Body $body

# Don't ignore self signed certificates anymore
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null

if (-Not $response.results) {
	Write-Host "Service: $servicename on host: $hostname does not exist!"
    exit 3
}	

# Icinga stuff
$Uri = "https://" + $icingaHost + ":" + $apiPort + "/v1/actions/process-check-result"
$headers = @{ "Authorization" = "$basicAuthValue"; "Accept" = "application/json" }
$body = @{
    type            = 'Service'
    filter          = 'host.name=="' + $hostname + '" && service.name=="' + $servicename + '"'
    exit_status     = $exit_status
	plugin_output	= $plugin_output
	check_source	= $hostname
}

if ($perfdata) {
	$body.Add("perfdata", $perfdata)
}

if ($ttl) {
	$body.Add("ttl", $ttl)
}
# $body = $body | ConvertTo-Json | %{[Regex]::Replace($_, "\\u(?<Value>[a-zA-Z0-9]{4})", { param($m) ([char]([int]::Parse($m.Groups['Value'].Value, [System.Globalization.NumberStyles]::HexNumber))).ToString() } )}
$body = $body | ConvertTo-Json

# Ignore self signed certificates
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
# Schedule the downtime
$response = try { Invoke-RestMethod -Headers $headers -Uri $Uri -Method Post -ContentType 'application/json' -Body $body } catch { $error = "StatusCode: " + $_.Exception.Response.StatusCode.value__ ; $error += " StatusDescription: " + $_.Exception.Response.StatusDescription 	}
# Don't ignore self signed certificates anymore
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = $null
if ($error) {
	Write-Host "Something went wrong!" $error
	exit 4
}	

if ($response.results.code -gt 200) {
	Write-Host "Couold not send passive results!"
}	

Regards,
Carsten

1 Like

I don’t have time right now to test it, so could you shows an output?

If everything is ok there is no output. On errors or non existing services it will write what did go wrong