What is this?

This knowledgebase contains questions and answers about PRTG Network Monitor and network monitoring in general.

Learn more

PRTG Network Monitor

Intuitive to Use. Easy to manage.
More than 500,000 users rely on Paessler PRTG every day. Find out how you can reduce cost, increase QoS and ease planning, as well.

Free Download

Top Tags


View all Tags

Can I check for specific HTTP response codes with PRTG?

Votes:

4

Can I check for specific HTTP Response codes with PRTG?

custom custom-script-exe exe-script-sensor http http-response-code prtg response vbscript

Created on Feb 11, 2013 6:35:24 AM by  Konstantin Wolff [Paessler Support]

Last change on Dec 3, 2020 12:42:45 PM by  Brandy Greger [Paessler Support]



Best Answer

Accepted Answer

Votes:

3

If someone needs a Powershell variant to use with an EXE/Script Advanced sensor:

<#
	.SYNOPSIS
		Query an HTTP Endpoint to Measure the Response Time and the HTTP Status Code

	.DESCRIPTION
		This script is able to query an HTTP/HTTPS Endpoint and measure the response time as well as the HTTP Status Code. The script is designed to be used with PRTG Network Monitor (https://www.paessler.com/prtg).

	.PARAMETER Url
		The Uniform Resource Locator (URL) you want to query, including the protocol (and path).: https://example.org or http://example.com:8080/myfile.htm

	.PARAMETER Timeout
		The number of seconds to wait for the HTTP query to complete (Default: 30)

	.PARAMETER TrustAllCerts
		Use this option to ignore any SSL Certificate issues and use all possible protocol versions

	.EXAMPLE
		Running the script interactively to test it:
		PS> .\Get-HTTPStatusCode.ps1 -Url "https://example.org/" -Timeout 10

	.EXAMPLE
		For running the script in PRTG, you can use PRTG's placeholders to make the setup more robust:
		Parameters(in the Sensor's settings): -Url "https://%host/" -Timeout 10

		However, it's also possible to enter the full URL in the sensor as expected:
		Parameters(in the Sensor's settings): -Url "https://example.org/" -Timeout 10

	.EXAMPLE
		If you're monitoring an endpoint with an invalid certificate (expired, self-signed, etc) you can enable the TrustAllCerts switch, like this:
		PS> .\Get-HTTPStatusCode.ps1 -Url "https://invalidsslserver.example.org/" -Timeout 10 -TrustAllCerts

	.NOTES
		Version: 2.5.20230920
		Author: Luciano Lingnau, Paessler AG (https://www.paessler.com/)

	.LINK
		https://kb.paessler.com/en/topic/47373
#>

#Requires -Version 3.0

param(
	[Parameter(Mandatory=$true)]
	[string]$Url,
	[int]$Timeout = "30",
	[switch]$TrustAllCerts = $false
)

[string]$sensorMessage = ''
$errorFlag = $false
$results = @()

#Avoid issues with weird SSL Certificates (Self-signed, expired, etc)
#Should only be used when a trusted certificate is not an option
if ($TrustAllCerts){
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

#Define Accepted SSL/TLS Versions, if unset this will be differentl depending on the OS and PS Version
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12,Tls13'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

try {
	#Stopwatch used to time the lenghtiest part of the execution (long execution times could be an issue)
	$exectime = [System.Diagnostics.Stopwatch]::StartNew()

	$a = Invoke-WebRequest -Uri $Url -TimeoutSec $Timeout -UseBasicParsing -ErrorAction SilentlyContinue

	#Stop Stopwatch used to time the lenghtiest part of the execution
	$exectime.Stop()

	#Parse the results in a PRTG Friendly way
	if ($a.StatusCode){
		$results += @{
			Channel = 'Status Code'
			Value = $a.StatusCode
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Length'
			Value = $a.RawContentLength
			Unit = 'BytesFile'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
	}

    $sensorMessage = "$($url)"

} catch {

	#If there is a valid statuscode in the response (like 3XX) we want that to be a sensor result, so this has to be handled in the try/catch

    if ($_.Exception.Response.StatusCode.Value__ -gt 0){

		#Parse the results in a PRTG Friendly way
		$results += @{
			Channel = 'Status Code'
			Value = $_.Exception.Response.StatusCode.Value__
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Length'
			Value = '-1'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
		
		$sensorMessage = "$($url)"

	}else{

		#Otherwise it's an exception that doesn't have a valid result

		$errorFlag  = $true
		$sensorMessage = "Exception (Line $($_.InvocationInfo.ScriptLineNumber)): $($_.Exception.Message)"
	}

}

$sensorResult = '' | Select-Object prtg
if ($errorFlag) {
	$sensorResult.prtg = '' | Select-Object error
	$sensorResult.prtg.error = 1
} else {
	$sensorResult.prtg = '' | Select-Object result
	$sensorResult.prtg.result = $results
}
if ($sensorMessage) {
	$sensorResult.prtg | Add-Member -MemberType NoteProperty -Name 'text' -Value $null
	$sensorResult.prtg.text = $sensorMessage
}
$sensorResult | ConvertTo-Json -Depth 5 | Write-Output

In order to pass the url from the sensor's settings, enter it like this in the "Parameters" field: -Url "https://example.org/" -Timeout 10

Using %host in the parameters as a placeholder like this will also work: -Url "https://%host/" -Timeout 10

And if you're encountering issues with SSL (Such as the error "The request was aborted: Could not create SSL/TLS secure channel."), try adding TrustAllCerts to the parameters: -Url "https://%host/" -Timeout 10 -TrustAllCerts

The channel displaying the return code uses an already existing lookup (prtg.standardlookups.http.statuscode) to evaluate which codes are regarded as OK/Warning/Error. Feel free to create a custom lookup based on the existing one if you need.

On a side-note: There's also another lookup called "prtg.standardlookups.http.statuscodedetailed" which contains definitions for every single return code, instead of ranges as in "prtg.standardlookups.http.statuscode".

Changelog:
  • 20/09/2023 - Version 2.5 adds the missing documentation for the TrustAllCerts parameter. Also adds support for TLS1.3 when TrustAllCerts is used.
  • 04/07/2022 - Version 2.4 changes the unit for the "Length" channel to Bytes so that the value can also be displayed in a more user-friendly format in PRTG. This only applies to newly created sensors and existing sensors may keep working but will still just display a number (without unit) as value.
  • 04/07/2022 - Version 2.3 makes the -TrustAllCerts also accept any Security Protocol, previously the script would behaved differently depending on different OS's and Powershell versions. Thanks to user Mihai for reporting this.
  • 17/03/2022 - Version 2.2 completely changes the code to a more modular approach which is easier to maintain. Functionally almost identical to 1.0
  • 09/03/2022 - Version 1.0 includes some bigger changes and is not backwards compatible (the parameters changed slightly). What's new: Invalid certificates are now only accepted when the switch-parameter TrustAllCerts is set. Otherwise you will see an SSL Error. Also fixed a small issue with the units from the ExecTime channel. Added better documentation and examples in the code itself
  • 01/09/2021 - Switched from Write-Host to Write-Output to conform with new "PowerShell Security Enhancement" (As of PRTG 21.2.68).
  • 25/06/2018 - Modified the try/catch to properly read the status code when it is part of an exception. When this happens, the Length is reported as -1.
  • 10/04/2018 - Added code to ignore SSL Certificate errors.
  • 28/07/2017 - Included a parameter for timeout. Default = 10 (seconds).

Created on Jan 4, 2017 7:53:50 AM by  Luciano Lingnau [Paessler]

Last change on Sep 20, 2023 6:17:51 AM by  Luciano Lingnau [Paessler]



28 Replies

Votes:

2

There is no native Sensor within PRTG which can do this but you may use the following script in addition to a EXE/Script Sensor:

sUrl = "http://www.google.com"
sStatusToCheck = 200


If Wscript.Arguments.Count = 1 then
    sUrl = Wscript.Arguments(0)
End If

If Wscript.Arguments.Count = 2 then
    sUrl = Wscript.Arguments(0)
    sStatusToCheck = Wscript.Arguments(1)
End If

Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP.3.0")

oXMLHTTP.Open "GET", sUrl, False, " "," "
oXMLHTTP.Send

WScript.Echo oXMLHTTP.Status & ":" & oXMLHTTP.StatusText

If oXMLHTTP.Status = sStatusToCheck then
    WScript.Quit("0")
Else
    WScript.Quit("2")
End If

The script can be called with parameters, where the first parameter has to be the URL and the second parameter has to be the Status Code to check for (e.g. 200,401,...).

Kudos for the script go to PRTG User Colby.

Created on Feb 11, 2013 8:51:35 AM by  Konstantin Wolff [Paessler Support]



Votes:

0

Nice script! Thnx! I extended it a bit, by disabling redirects, adding post values and extending error handling:

'************************************************
'**  Init
'************************************************
Option Explicit
Dim oXMLHTTP
Dim url, postParameter
Const WinHttpRequestOption_EnableRedirects = 6

'************************************************
'**  Configuration parameters
'************************************************
url				= "http://www.google.com"
postParameter	= ""

'************************************************
'**  Main
'************************************************
If Wscript.Arguments.Count = 1 then
    url				= Wscript.Arguments(0)
ElseIf Wscript.Arguments.Count = 2 then
    url				= Wscript.Arguments(0)
    postParameter	= Wscript.Arguments(1)
End If

Set oXMLHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")

oXMLHTTP.Option(WinHttpRequestOption_EnableRedirects)	= false
oXMLHTTP.Open "POST", url, False
oXMLHTTP.Send postParameter

'************************************************
'**  Return value
'************************************************
If Err.Number = 0 Then
	WScript.Echo oXMLHTTP.Status & ":" & oXMLHTTP.StatusText
	WScript.Quit(0)
Else
	WScript.Quit(2)
End If

Created on Mar 27, 2013 10:55:26 AM

Last change on Mar 27, 2013 11:52:18 AM by  Konstantin Wolff [Paessler Support]



Votes:

0

Here is an updated version, I believe there was a bug with Konstantin's version: when sStatusToCheck is given as argument, it is cast as string, not int, so the status part of the script should be:

[...] If oXMLHTTP.Status = CInt(sStatusToCheck) then [...]

Here is a revised version (note: http only, https support should be fairly easy, or duplicate the check):

'******************************************************************************
'** Script to check a specific HTTP return code
'** 
'** Authors: PRTG User Colby, Konstantin Wolff (Paessler Support), Thomas Blanchard - [email protected]
'** Version: 0.01
'** Version Date: 2014-12-03
'** Source: 
'** 	- https://kb.paessler.com/en/topic/47373-can-i-check-for-specific-http-response-codes-with-prtg
'******************************************************************************

sHost = "www.lynda.com"
sStatusToCheck = 200

If Wscript.Arguments.Count = 1 then
    sHost = Wscript.Arguments(0)
End If

If Wscript.Arguments.Count = 2 then
    sHost = Wscript.Arguments(0)
    sStatusToCheck = Wscript.Arguments(1)
End If

sUrl = "http://" & sHost & "/"
' WScript.Echo sUrl & " " & sStatusToCheck

Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP.3.0")

oXMLHTTP.Open "GET", sUrl, False, " "," "
oXMLHTTP.Send

sMsg = sHost & " returns " & oXMLHTTP.Status & " " & oXMLHTTP.StatusText & " (expecting " & sStatusToCheck & ")"

If oXMLHTTP.Status = CInt(sStatusToCheck) then
	WScript.Echo oXMLHTTP.Status & ":OK " & sMsg
    WScript.Quit("0")
Else
	WScript.Echo oXMLHTTP.Status & ":ERROR " & sMsg
    WScript.Quit("2")
End If

Created on Dec 3, 2014 2:53:15 PM



Votes:

0

Can you please post how should parameters be typed for different url and status code? I can not get it work with parameters.

Created on Aug 13, 2015 10:14:13 AM



Votes:

0

Hi Ozgur,

You can also try the following PowerShell script: http://pastebin.com/KpCSbrzt

Call it with the following parameters:
-URL "www.google.de" -ResponseCode 220 -Protocol "HTTP"

Note Remember to execute a PowerShell (x86) with admin privileges and run Set-ExecutionPolicy RemoteSigned

...in order to make the script work :)

Created on Aug 14, 2015 12:52:01 PM by  Stephan Linke [Paessler Support]



Votes:

0

Hello,

I am currently running the Powershell script that Stephan posted, and the script itself is running correctly (from what I can tell). PRTG, however, is not picking up on the value that the script is putting out, and I am getting "Unauthorized access" as the last message. Any thoughts?

Created on Dec 8, 2015 5:45:40 PM



Votes:

0

What URL are you trying to check?

Created on Dec 8, 2015 6:51:30 PM by  Stephan Linke [Paessler Support]



Votes:

0

Created on Dec 29, 2015 4:32:06 PM



Votes:

0

Stephan,

I modified your version of the Powershell script (see below) so that I am able to successfully get response codes in our environment. PRTG is giving me an "Unauthorized Access" error when I tell the EXE/Script Sensor to run it. Any thoughts?

param(
    [string]$URL,
    [int]$ResponseCode1 = "",
    [int]$ResponseCode2 = "200",
    [string]$DefaultDNS = "false",
    [string]$protocol = "https",
    [string]$HeaderHost = "https://mobile.processnow.com"
    ) 
 
# Ignore SSL errors
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
 
$URL = $HeaderHost
$req = [system.Net.WebRequest]::Create($URL)


       
 
# Add some headers to the web request (for round robin dns and load balancers)
#$req.$Host = $HeaderHost;
$req.AllowAutoRedirect=$true
# catch exceptions
try                                                     { $res = $req.GetResponse() }
catch [System.Net.WebException] { $res = $_.Exception.Response }
 
 
# get the numeric response code of the request
$ResponseCode1 = (($res.StatusCode) -as [int])
 
# and some error handling
if([int]$ResponseCode1 -eq [int]$ResponseCode2){
    Write-Host $ResponseCode2":Page returned HTTP code "$ResponseCode1" as expected (used "$URL").";
    exit 0;
}
 
elseif([int]$ResponseCode1 -eq 200){
        Write-Host $ResponseCode1":Connection error (used "$URL").";
}
 
else{
    Write-Host $ResponseCode1":Page returned "$ResponseCode1" instead of $ResponseCode2 unexpectedly (used "$URL").";
}

Created on Dec 29, 2015 7:06:19 PM

Last change on Dec 30, 2015 8:09:31 AM by  Torsten Lindner [Paessler Support]



Votes:

0

Can you post your sensor settings? You probably have to set "Use security context of parent device" in the sensor security context settings. Can you check that?

Created on Dec 31, 2015 1:30:58 PM by  Stephan Linke [Paessler Support]



Votes:

0

I have set the security settings to "Use security context of parent device." I am still getting Unauthorized Access, however I am showing that the value is 0. According to the manual, the #0 indicates that the script is running ok. Right?

Created on Dec 31, 2015 6:05:31 PM



Votes:

0

Are you using a proxy server by any chance? What's the output of the script when run in PowerShell?

Created on Jan 4, 2016 8:20:58 PM by  Stephan Linke [Paessler Support]



Votes:

0

We do have proxies setup between the two locations.

When I run the script manually in Powershell, the output is this:

200:Page returned HTTP code 200 as expected (used https://register.processnow.com).

Created on Jan 5, 2016 5:57:40 PM



Votes:

0

Is the proxy server configured via GPO? Or via IE? Can you try a different windows user in the parent device credential settings? Probably your own user account?

Created on Jan 6, 2016 9:21:28 AM by  Stephan Linke [Paessler Support]



Accepted Answer

Votes:

3

If someone needs a Powershell variant to use with an EXE/Script Advanced sensor:

<#
	.SYNOPSIS
		Query an HTTP Endpoint to Measure the Response Time and the HTTP Status Code

	.DESCRIPTION
		This script is able to query an HTTP/HTTPS Endpoint and measure the response time as well as the HTTP Status Code. The script is designed to be used with PRTG Network Monitor (https://www.paessler.com/prtg).

	.PARAMETER Url
		The Uniform Resource Locator (URL) you want to query, including the protocol (and path).: https://example.org or http://example.com:8080/myfile.htm

	.PARAMETER Timeout
		The number of seconds to wait for the HTTP query to complete (Default: 30)

	.PARAMETER TrustAllCerts
		Use this option to ignore any SSL Certificate issues and use all possible protocol versions

	.EXAMPLE
		Running the script interactively to test it:
		PS> .\Get-HTTPStatusCode.ps1 -Url "https://example.org/" -Timeout 10

	.EXAMPLE
		For running the script in PRTG, you can use PRTG's placeholders to make the setup more robust:
		Parameters(in the Sensor's settings): -Url "https://%host/" -Timeout 10

		However, it's also possible to enter the full URL in the sensor as expected:
		Parameters(in the Sensor's settings): -Url "https://example.org/" -Timeout 10

	.EXAMPLE
		If you're monitoring an endpoint with an invalid certificate (expired, self-signed, etc) you can enable the TrustAllCerts switch, like this:
		PS> .\Get-HTTPStatusCode.ps1 -Url "https://invalidsslserver.example.org/" -Timeout 10 -TrustAllCerts

	.NOTES
		Version: 2.5.20230920
		Author: Luciano Lingnau, Paessler AG (https://www.paessler.com/)

	.LINK
		https://kb.paessler.com/en/topic/47373
#>

#Requires -Version 3.0

param(
	[Parameter(Mandatory=$true)]
	[string]$Url,
	[int]$Timeout = "30",
	[switch]$TrustAllCerts = $false
)

[string]$sensorMessage = ''
$errorFlag = $false
$results = @()

#Avoid issues with weird SSL Certificates (Self-signed, expired, etc)
#Should only be used when a trusted certificate is not an option
if ($TrustAllCerts){
add-type @"
    using System.Net;
    using System.Security.Cryptography.X509Certificates;
    public class TrustAllCertsPolicy : ICertificatePolicy {
        public bool CheckValidationResult(
            ServicePoint srvPoint, X509Certificate certificate,
            WebRequest request, int certificateProblem) {
            return true;
        }
    }
"@

#Define Accepted SSL/TLS Versions, if unset this will be differentl depending on the OS and PS Version
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12,Tls13'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

try {
	#Stopwatch used to time the lenghtiest part of the execution (long execution times could be an issue)
	$exectime = [System.Diagnostics.Stopwatch]::StartNew()

	$a = Invoke-WebRequest -Uri $Url -TimeoutSec $Timeout -UseBasicParsing -ErrorAction SilentlyContinue

	#Stop Stopwatch used to time the lenghtiest part of the execution
	$exectime.Stop()

	#Parse the results in a PRTG Friendly way
	if ($a.StatusCode){
		$results += @{
			Channel = 'Status Code'
			Value = $a.StatusCode
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Length'
			Value = $a.RawContentLength
			Unit = 'BytesFile'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
	}

    $sensorMessage = "$($url)"

} catch {

	#If there is a valid statuscode in the response (like 3XX) we want that to be a sensor result, so this has to be handled in the try/catch

    if ($_.Exception.Response.StatusCode.Value__ -gt 0){

		#Parse the results in a PRTG Friendly way
		$results += @{
			Channel = 'Status Code'
			Value = $_.Exception.Response.StatusCode.Value__
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Length'
			Value = '-1'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
		
		$sensorMessage = "$($url)"

	}else{

		#Otherwise it's an exception that doesn't have a valid result

		$errorFlag  = $true
		$sensorMessage = "Exception (Line $($_.InvocationInfo.ScriptLineNumber)): $($_.Exception.Message)"
	}

}

$sensorResult = '' | Select-Object prtg
if ($errorFlag) {
	$sensorResult.prtg = '' | Select-Object error
	$sensorResult.prtg.error = 1
} else {
	$sensorResult.prtg = '' | Select-Object result
	$sensorResult.prtg.result = $results
}
if ($sensorMessage) {
	$sensorResult.prtg | Add-Member -MemberType NoteProperty -Name 'text' -Value $null
	$sensorResult.prtg.text = $sensorMessage
}
$sensorResult | ConvertTo-Json -Depth 5 | Write-Output

In order to pass the url from the sensor's settings, enter it like this in the "Parameters" field: -Url "https://example.org/" -Timeout 10

Using %host in the parameters as a placeholder like this will also work: -Url "https://%host/" -Timeout 10

And if you're encountering issues with SSL (Such as the error "The request was aborted: Could not create SSL/TLS secure channel."), try adding TrustAllCerts to the parameters: -Url "https://%host/" -Timeout 10 -TrustAllCerts

The channel displaying the return code uses an already existing lookup (prtg.standardlookups.http.statuscode) to evaluate which codes are regarded as OK/Warning/Error. Feel free to create a custom lookup based on the existing one if you need.

On a side-note: There's also another lookup called "prtg.standardlookups.http.statuscodedetailed" which contains definitions for every single return code, instead of ranges as in "prtg.standardlookups.http.statuscode".

Changelog:
  • 20/09/2023 - Version 2.5 adds the missing documentation for the TrustAllCerts parameter. Also adds support for TLS1.3 when TrustAllCerts is used.
  • 04/07/2022 - Version 2.4 changes the unit for the "Length" channel to Bytes so that the value can also be displayed in a more user-friendly format in PRTG. This only applies to newly created sensors and existing sensors may keep working but will still just display a number (without unit) as value.
  • 04/07/2022 - Version 2.3 makes the -TrustAllCerts also accept any Security Protocol, previously the script would behaved differently depending on different OS's and Powershell versions. Thanks to user Mihai for reporting this.
  • 17/03/2022 - Version 2.2 completely changes the code to a more modular approach which is easier to maintain. Functionally almost identical to 1.0
  • 09/03/2022 - Version 1.0 includes some bigger changes and is not backwards compatible (the parameters changed slightly). What's new: Invalid certificates are now only accepted when the switch-parameter TrustAllCerts is set. Otherwise you will see an SSL Error. Also fixed a small issue with the units from the ExecTime channel. Added better documentation and examples in the code itself
  • 01/09/2021 - Switched from Write-Host to Write-Output to conform with new "PowerShell Security Enhancement" (As of PRTG 21.2.68).
  • 25/06/2018 - Modified the try/catch to properly read the status code when it is part of an exception. When this happens, the Length is reported as -1.
  • 10/04/2018 - Added code to ignore SSL Certificate errors.
  • 28/07/2017 - Included a parameter for timeout. Default = 10 (seconds).

Created on Jan 4, 2017 7:53:50 AM by  Luciano Lingnau [Paessler]

Last change on Sep 20, 2023 6:17:51 AM by  Luciano Lingnau [Paessler]



Votes:

0

Hello,

How does it work with https? I have some Login-Sites which i can monitor with this script. I can open them with http and https. on one of the Server,only https is active an the other Servers will follow in time. on the Server with only https i get "Query Failed: Unable to connect to the server", wehne I use the "best Answer" script.

I really need help to monitor the https login

Created on Apr 9, 2018 10:51:43 AM



Votes:

0

Hi there,

PowerShell is rather picky with its TLS connections. Kindly use the updated version in the best answer, I modified it to support self-signed certificates :)


Kind regards,
Stephan Linke, Tech Support Team

Created on Apr 10, 2018 12:57:02 PM by  Stephan Linke [Paessler Support]



Votes:

0

Hi, thank your for providing this script. I have a problem with the script and Windows Server 2019. I get following error when starting it with prtg: This version of %1 is not compatible with the version of Windows you're running. Check your computer's system information and then contact the software publisher. (0xD8)

Does anybody know what to change to make it work?

Thank you in advance

Created on Dec 6, 2019 10:47:51 AM



Votes:

0

What do your parameters look like and did you check our guide regarding custom PowerShell based Sensors?

Created on Dec 6, 2019 12:19:10 PM by  Stephan Linke [Paessler Support]

Last change on Dec 6, 2019 12:19:16 PM by  Stephan Linke [Paessler Support]



Votes:

0

Is the URL available without any authentication? And is that the actual URL? What error do you get?

Created on Dec 13, 2019 8:41:20 AM by  Stephan Linke [Paessler Support]



Votes:

1

I´ve found the issue. I had the wrong file extension (not .ps1)

Created on Dec 13, 2019 9:26:19 AM



Votes:

0

@ Luciano Lingnau,

I've tried using the latest script posted but having an error on PRTG. Any thoughts?

Below is the error though i can ran the script successfully on a device.

Sensor Custom EXE/Script Sensor Response not well-formed: "(add-type : (0) : Source file 'C:\windows\TEMP\205ir4ea.0.cs' could not be found (1) : using System.Net; At C:\Program Files (x86)\PRTG Network Monitor\custom sensors\EXE\2_EPHD_URL_Response_Code.ps1:6 char:1 + add-type @" + ~~~~~~~~~~~ + CategoryInfo : InvalidData: (error CS2001: S...ld not be found: CompilerError) [Add-Type], Exception + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands. AddTypeCommand add-type : (0) : No source files specified (1) : using System.Net; At C:\Program Files (x86)\PRTG Network Monitor\custom sensors\EXE\2_EPHD_URL_Response_Code.ps1:6 char:1 + add-type @" + ~~~~~~~~~~~ + CategoryInfo : InvalidData: (warning CS2008:...files specified: CompilerError) [Add-Type], Exception + FullyQualifiedErrorId : SOURCE_CODE_ERROR,Microsoft.PowerShell.Commands. AddTypeCommand add-type : Cannot add type. Compilation errors occurred. At C:\Program Files (x86)\PRTG Network Monitor\custom sensors\EXE\2_EPHD_URL_Response_Code.ps1:6 char:1 + add-type @" + ~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationExc eption + FullyQualifiedErrorId : COMPILER_ERRORS,Microsoft.PowerShell.Commands.Ad dTypeCommand <prtg> <result> <channel>Status Code</channel> <value>401</value> <valuelookup>prtg.standardlookups.http.statuscodedetailed_401</valuelookup> </result> <result> <channel>Length</channel> <value>-1</value> </result> <result> <channel>ExecTime</channel> <value>58</value> <CustomUnit>msecs</CustomUnit> </result> <text>https://phd.onefluor.com/#/login</text> </prtg> )" (code: PE132)

Created on Nov 6, 2020 12:10:26 AM

Last change on Nov 6, 2020 8:59:09 AM by  Stephan Linke [Paessler Support]



Votes:

0

What's the output of $PSVersiontable (in PowerShell)?

Created on Nov 6, 2020 8:59:57 AM by  Stephan Linke [Paessler Support]

Last change on Nov 6, 2020 9:00:07 AM by  Stephan Linke [Paessler Support]



Votes:

0

@Luciano Lingnau thank you for the script it worked very good in my own environment, when I moved the script to the company it did not want to connect to the url because of ssl connection, so I had to add two more lines to the code for it to work ( even adding -TrustAllCerts did not do the trick ).

$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12' [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

so the final product is:

param(
	[Parameter(Mandatory=$true)]
	[string]$Url,
	[int]$Timeout = "30",
	[switch]$TrustAllCerts = $false
)

[string]$sensorMessage = ''
$errorFlag = $false
$results = @()

#Avoid issues with weird SSL Certificates (Self-signed, expired, etc)
#Should only be used when a trusted certificate is not an option
if ($TrustAllCerts){
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

try {
	#Stopwatch used to time the lenghtiest part of the execution (long execution times could be an issue)
	$exectime = [System.Diagnostics.Stopwatch]::StartNew()

	$a = Invoke-WebRequest  -UseBasicParsing -Uri $Url -TimeoutSec $Timeout -ErrorAction SilentlyContinue

	#Stop Stopwatch used to time the lenghtiest part of the execution
	$exectime.Stop()

	#Parse the results in a PRTG Friendly way
	if ($a.StatusCode){
		$results += @{
			Channel = 'Status Code'
			Value = $a.StatusCode
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
	}

    $sensorMessage = "$($url)"

} catch {

	#If there is a valid statuscode in the response (like 3XX) we want that to be a sensor result, so this has to be handled in the try/catch

    if ($_.Exception.Response.StatusCode.Value__ -gt 0){

		#Parse the results in a PRTG Friendly way
		$results += @{
			Channel = 'Status Code'
			Value = $_.Exception.Response.StatusCode.Value__
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
		
		$sensorMessage = "$($url)"

	}else{

		#Otherwise it's an exception that doesn't have a valid result

		$errorFlag  = $true
		$sensorMessage = "Exception (Line $($_.InvocationInfo.ScriptLineNumber)): $($_.Exception.Message)"
	}

}

$sensorResult = '' | Select-Object prtg
if ($errorFlag) {
	$sensorResult.prtg = '' | Select-Object error
	$sensorResult.prtg.error = 1
} else {
	$sensorResult.prtg = '' | Select-Object result
	$sensorResult.prtg.result = $results
}
if ($sensorMessage) {
	$sensorResult.prtg | Add-Member -MemberType NoteProperty -Name 'text' -Value $null
	$sensorResult.prtg.text = $sensorMessage
}
$sensorResult | ConvertTo-Json -Depth 5 | Write-Output

P.S: I did not understood the need for the Lenght result so I deleted it. I am using theprtg.standardlookups.http.statuscodedetailed lookup and it does wonders, thank you lots!

Created on Jun 16, 2022 8:45:29 AM



Votes:

1

Hello Mihai Leca,
thank you for your reply and kind feedback!

From what I've seen recently, different powershell versions and host operating systems will have their own nitpicks with SSL endpoints in powershell. I will consider updating the default script to include the code you've suggested :)

And as for the "Length" channel, I've included it because there are probably cases where this is relevant. And because the HTTP Advanced sensor also includes this channel by default(Length). And this sensor is meant as a custom alternative to the HTTP Advanced sensor.

But either way, I'm really happy to hear the code/sensor was helpful to you.

Best Regards,
Luciano Lingnau [Paessler]

Created on Jun 20, 2022 6:53:17 AM by  Luciano Lingnau [Paessler]

Last change on Jul 4, 2022 7:31:23 AM by  Luciano Lingnau [Paessler]



Votes:

1

Hi Luciano,

Thank you for the kind response, did not expect it :D

About the length, I meant, I did not understood what it meant and what is the value returned and that is why I've deleted it.

Also today, I needed to access a page with basic authentication but the PRTG sensor did not have an login option so I've added into the code the following line:

-Headers @{ Authorization = "Basic Zm9vOmJhcg=="+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) } 

So now you can use the sensors on the

So the end result was:

 param(
	[Parameter(Mandatory=$true)]
	[string]$Url,
	[int]$Timeout = "60",
	[switch]$TrustAllCerts = $false
)

[string]$sensorMessage = ''
$errorFlag = $false
$results = @()

#Avoid issues with weird SSL Certificates (Self-signed, expired, etc)
#Should only be used when a trusted certificate is not an option
if ($TrustAllCerts){
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
    public bool CheckValidationResult(
        ServicePoint srvPoint, X509Certificate certificate,
        WebRequest request, int certificateProblem) {
        return true;
    }
}
"@
$AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
[System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}

try {
	#Stopwatch used to time the lenghtiest part of the execution (long execution times could be an issue)
	$exectime = [System.Diagnostics.Stopwatch]::StartNew()

	$a = Invoke-WebRequest  -UseBasicParsing -Uri $Url -Headers @{ Authorization = "Basic Zm9vOmJhcg=="+ [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("user:pass")) } -TimeoutSec $Timeout -ErrorAction SilentlyContinue

	#Stop Stopwatch used to time the lenghtiest part of the execution
	$exectime.Stop()

	#Parse the results in a PRTG Friendly way
	if ($a.StatusCode){
		$results += @{
			Channel = 'Status Code'
			Value = $a.StatusCode
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
	}

    $sensorMessage = "$($url)"

} catch {

	#If there is a valid statuscode in the response (like 3XX) we want that to be a sensor result, so this has to be handled in the try/catch

    if ($_.Exception.Response.StatusCode.Value__ -gt 0){

		#Parse the results in a PRTG Friendly way
		$results += @{
			Channel = 'Status Code'
			Value = $_.Exception.Response.StatusCode.Value__
			valuelookup = 'prtg.standardlookups.http.statuscode'
		}
		$results += @{
			Channel = 'Execution Time'
			Value = $exectime.ElapsedMilliseconds
			Unit = 'TimeResponse'
		}
		
		$sensorMessage = "$($url)"

	}else{

		#Otherwise it's an exception that doesn't have a valid result

		$errorFlag  = $true
		$sensorMessage = "Exception (Line $($_.InvocationInfo.ScriptLineNumber)): $($_.Exception.Message)"
	}

}

$sensorResult = '' | Select-Object prtg
if ($errorFlag) {
	$sensorResult.prtg = '' | Select-Object error
	$sensorResult.prtg.error = 1
} else {
	$sensorResult.prtg = '' | Select-Object result
	$sensorResult.prtg.result = $results
}
if ($sensorMessage) {
	$sensorResult.prtg | Add-Member -MemberType NoteProperty -Name 'text' -Value $null
	$sensorResult.prtg.text = $sensorMessage
}
$sensorResult | ConvertTo-Json -Depth 5 | Write-Output 

PS. From testing all types of http response codes I've seen that the 10 second timeout line is not enough to catch 500 type errors and you get error on line 74 in PRTG since the page loads in 12-13 seconds due to the error so I advice on changing the Timeout to 30 seconds to 1 minute to be able to catch all types of http error codes.

Thank you again Luciano, good day!

Created on Jun 27, 2022 6:43:37 AM

Last change on Jul 4, 2022 6:46:38 AM by  Luciano Lingnau [Paessler]



Votes:

1

Hello @Luciano,

Regarding the Lenght, I did not understand what the lookup returns as a value.

P.S

I've needed to access a page that has basic http authentication with this script and I've added the following line:

@{ Authorization = "Basic Zm9vOmJhcg=="}

In line 35 of the script resulting in: $a = Invoke-WebRequest -UseBasicParsing -Uri $Url -Headers @{ Authorization = "Basic Zm9vOmJhcg=="} -TimeoutSec $Timeout -ErrorAction SilentlyContinue

If the script does not see any authentication on the webpage it will proceede to scanning the page for the http response code,

Again, thank you!

Created on Jul 1, 2022 9:57:43 AM



Votes:

0

Hello Mihai Leca,
thank you for sharing your findings again.

I have now updated the reference script based on your input from Jun 16, 2022 and included the code to accept any security protocol in the TrustAllCerts option. :)

I also used this opportunity to define a proper unit for the Length channel, to make it easier to comprehend.

Also thank you for sharing your additional findings with the community. And it makes us happy to hear that you've been able to further customize to script exactly to your needs.

Regarding the Lenght, I did not understand what the lookup returns as a value.

I'm not quite sure I understand what you mean, as there is no lookup assigned to the Length channel by default. This is the default sensor output (of the base script):

PS C:\Users\llingnau\Downloads> .\Get-HTTPStatusCode.ps1 -Url "https://www.paessler.com" -TrustAllCerts
{
    "prtg":  {
                 "result":  [
                                {
                                    "Channel":  "Status Code",
                                    "valuelookup":  "prtg.standardlookups.http.statuscode",
                                    "Value":  200
                                },
                                {
                                    "Channel":  "Length",
                                    "Value":  288738
                                },
                                {
                                    "Channel":  "Execution Time",
                                    "Value":  225,
                                    "Unit":  "TimeResponse"
                                }
                            ],
                 "text":  "https://www.paessler.com"
             }
}

Best Regards,
Luciano Lingnau [Paessler]

Created on Jul 4, 2022 7:44:26 AM by  Luciano Lingnau [Paessler]

Last change on Jul 4, 2022 7:50:06 AM by  Luciano Lingnau [Paessler]




Disclaimer: The information in the Paessler Knowledge Base comes without warranty of any kind. Use at your own risk. Before applying any instructions please exercise proper system administrator housekeeping. You must make sure that a proper backup of all your data is available.