I need to check my websites, but they're behind a load balancer. I could circumvent it by using the "Host" header variable. Unfortunately, the HTTP sensors don't allow me to set it. Is there any way I can check my hosts anyway?


Article Comments

Introduction

This script will monitor a page for the returned result code and error if it doesn't match. You can also insert host headers according to your needs.

Requirements

This script was made for the EXE/Script (Advanced) sensor. Make sure that all the following prerequesites are met:

  1. PowerShell 3.0 or newer installed on the Core Server or the corresponding probe
  2. Set-ExecutionPolicy RemoteSigned executed in an administrative 32bit PowerShell
  3. Script is saved as PRTG-GetWebResponse.ps1 to <PRTG Application>Custom Sensors\EXEXML

Parameters

ParameterDescription
-SSLSimply enter this as parameter if the target host uses SSL
(only valid certificates supported)
-URLThe URL you want to check, e.g. www.google.com
-PortThe port you want to use
-ResponseCodeThe desired response code, e.g. 200
-HeadersThe headers you want to set. For example:
@{Host = "www.example.com"; Cookie = "expired"}
-TimeoutThe desired timeout

Version History

DateVersionNotes
31.08.20161.0Initial Release

Script

#requires -version 3.0
# ___ ___ _____ ___
#| _ \ _ \_   _/ __|
#|  _/   / | || (_ |
#|_| |_|_\ |_| \___|
#    NETWORK MONITOR
#-------------------
# Description: The script will check if a URL returns the expected return code and alert you if it doesn't
# Parameters:
# - URL: The site you want to check. Format: www.google.de
# - ResponseCode: The expected numerical response code (overview: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html).
# - SSL - If set, the request will be processed using HTTPS instead of HTTP
# - Headers: Modify the headers of the request, seperated by ;
# ------------------
# (c) 2016 Stephan Linke | Paessler AG
 
param(
    [switch]$SSL                             = $false,
    [string]$URL                             = "www.google.de",
    [int]$Port                               = 80,
    [int]$ResponseCode                       = 200,
    [System.Collections.ICollection]$Headers = @{Host = "www.example.com"},
    [int]$Timeout                            = 60
)

$result = @"
<?xml version=`"1.0`" encoding=`"UTF-8`" ?>
<prtg>
  <result>
    <Channel>Response Code</Channel>
    <Value>{0}</Value>
    <ValueLookup>prtg.standardlookups.http.statuscode</ValueLookup>
  </result>
  <result>
    <Channel>Response Time</Channel>
    <Value>{1}</Value>
    <Unit>Custom</Unit>
    <CustomUnit>Seconds</CustomUnit>
    <Float>1</Float>
    <DecimalMode>All</DecimalMode>
  </result>
  <text>{2}</text>
</prtg>
"@

# If there's an error, only this will be outputted
function This-PrtgError($Message){
    
    if(!($verbose)){
        Write-Host "<?xml version='1.0' encoding='UTF-8' ?><prtg>"
        Write-Host ([string]::Format("<error>1</error><text>{0}</text>",$Message));
        Write-Host "</prtg>";
    exit 0;
    }
}

function This-Exit([int]$ExitCode){
    if(!($psISE))
    { exit($ExitCode) }
}


function This-OpenURL(){

    try{

        # if we have an encrypted connection, use the corresponding protocol. 
        if($SSL){ $Protocol = "https" }
        else    { $Protocol = "http"  }

        $address = ([string]::Format("{0}://{1}:{2}/",$Protocol,$url,$Port))
        
        [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
        $sw = [system.diagnostics.stopwatch]::startNew()
        $Response = (Invoke-WebRequest -Headers $Headers -TimeoutSec $Timeout -Uri $address)
        $sw.Stop(); 

        $Result = @{
              ResponseCode = [int]$response.StatusCode
              UsedURL      = $address
              ResponseTime = $sw.elapsed.milliseconds / 1000 -replace ",",".";
        }


    } catch [exception] { 
        $Result = @{
              ResponseCode = [int]$response.StatusCode
              UsedURL      = $address
              ResponseTime = $sw.elapsed.milliseconds / 1000 -replace ",",".";
        }

    }
    return $Result;
}

$Response = (This-OpenURL)

# and some error handling
if($Response.ResponseCode -eq $ResponseCode){ 
    $message = [string]::Format("Page returned {0} as expected (used {1})",$Response.ResponseCode,$Response.UsedURL); 
    Write-Host ([string]::Format($result,$Response.ResponseCode,$Response.ResponseTime,$message))
    $ExitCode = 0 }
 
elseif($Response.ResponseCode -eq 0){ 
    $message = [string]::Format("A connection error has occured (used {0})",$Response.UsedURL); 
    This-PrtgError -Message $message }
 
else{ 
    $message = [string]::Format("Page returned {0} instead of {1} unexpectedly (used {2})",$Response.ResponseCode,$ResponseCode,$Response.UsedURL);
    This-PrtgError -Message $message }

This-Exit -ExitCode $ExitCode

Notes

The script is provided as is and may or may not work with your installation. If you need any further customizations for your environment, feel free to implement them. If you encounter any bugs, feel free to share them :)


Aug, 2016 - Permalink

Should this script still work under current releases? I'm not able to fill in the headers-parameter. I get the following error-message:

Script exit code was 0, but execution of the script returned an error state. Error Message: Cannot process argument transformation on parameter 'Headers'. Cannot convert the "@{host='something'}" value of type "System.String" to type "System.Collections.ICollection".

i've tried the following parameters: -url someUrl -port 80 -ResponseCode 200 -Headers @{"host"="something"} -url someUrl -port 80 -ResponseCode 200 -Headers "@{'host'='something'}" -url someUrl -port 80 -ResponseCode 200 -Headers @{host="something"}


Feb, 2022 - Permalink