We've written this script to extract some counter data from our software, The output looks to be formatted correctly but we are still getting the "XML: Junk after document element </prtg> -- JSON: The returned JSON does not match the expected structure (Invalid JSON.). (code: PE231)" error.

The values shown in the output are static, just trying to get something into prtg for now.

Below is the script and output.

Script

$baseURL = "http://ourservice/api/v1/"
$view = "ourservice"
$userName = ""
$password = ""
$application = "PRTG"
#$tagsToRead = @(($view + ".{Diagnostics}.Reading.TagHandles"); ($view + ".{Diagnostics}.Reading.NumClients"))
$tagsToRead = @(($view + ".{Diagnostics}.Reading.TagHandles"))

$authReqBody = "{ 'username':'$userName', 'password':'$password', 'timezone':'Eastern Standard Time', 'application':'$application' }"
$userToken = (Invoke-WebRequest -Uri $baseURL"getUserToken" -Method POST -Body $authReqBody | ConvertFrom-Json).userToken
$tagJson = $tagsToRead -join "','"
$reqBody = "{ 'userToken':'$userToken', 'tags': ['" + $tagJson + "'] }"
$tagData = (Invoke-WebRequest -Uri http://ourservice/api/v1/getTagData -Method POST -Body $reqBody).Content

$hashtable = @{}
(ConvertFrom-Json $tagData).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }

$hashtableData = @{}
foreach ($prop in $hashtable['data'].PSObject.Properties)
{
	$hashtableData[$prop.Name] = $prop.Value[1]
}

Write-Host @"
<prtg>
<result>
<channel>Handles</channel>
<value>24</value>
</result>
<result>
<channel>clients</channel>
<unit>clients</unit>
<value>4</value>
</result>
<text>Hello</text>
</prtg>
"@

$revokeBody = "{ 'userToken':'$userToken' }"
$revokeResponse = Invoke-WebRequest -Uri http://ourservice/api/v1/revokeUserToken -Method POST -Body $revokeBody 

Output

PS C:\Program Files (x86)\PRTG Network Monitor\Custom Sensors\EXEXML> .\GetDiagnostics.ps1 <prtg> <result> <channel>Handles</channel> <value>24</value> </result> <result> <channel>clients</channel> <unit>clients</unit> <value>4</value> </result> <text>Hello</text> </prtg>


Article Comments

Hello chrisbrooks, nice script and thank you for your clear inquiry.

Basically, I don't see any issues with the script. Especially, based on the output when you wan it manually. The output looks perfectly valid. I can only guess that the output when the script is run in PRTG is different. I encourage you to have a look here:

Specifically, the ExecutionPolicy configuration is mandatory to get this working from within PRTG (non-interactively).

Regardless of what the cause for the error is, seeing the actual content of the script when run by PRTG usually helps:

Within the Sensor's settings it is possible to set the "EXE Result" to "Write EXE result to disk". Once configured to do so a resulting Text File (Filename: 'Result of Sensor [ID].txt') will be stored under the Logs (Sensors) directory on the next scan of the sensor. This folder's path is by default "C:\ProgramData\Paessler\PRTG Network Monitor\" of the probe where the sensor is monitored.

I encourage you to enable this log and have a look at the logfile. If it doesn't make any sense to you, please share the output of the file(s) and I"ll be happy to have a look.

Ps.: It may be a wild guess, but I have seen a couple of cases in the past were Invoke-WebRequest needed the -UseBasicParsing as visible here to work when run by PRTG. You might want to try this as well.

Ps2.: User confirmed that -UseBasicParsing solved the issue. Here's the fixed version of the script:


Best Regards,
Luciano Lingnau [Paessler Support]


May, 2018 - Permalink

Hello Luciano,

Thank you for the reply. I have to be honest, I did not wrint the script, one of our developers crafted it, he is quite good at his work.

After reading your post I played with the -UseBasicParsing that switch resolved the issue we where seeing.

Thank you very much again, have a great day.

Regards, Chris


May, 2018 - Permalink

"Fixed" version of the script for reference:

$baseURL = "http://ourservice/api/v1/"
$view = "ourservice"
$userName = ""
$password = ""
$application = "PRTG"
#$tagsToRead = @(($view + ".{Diagnostics}.Reading.TagHandles"); ($view + ".{Diagnostics}.Reading.NumClients"))
$tagsToRead = @(($view + ".{Diagnostics}.Reading.TagHandles"))

$authReqBody = "{ 'username':'$userName', 'password':'$password', 'timezone':'Eastern Standard Time', 'application':'$application' }"
$userToken = (Invoke-WebRequest -Uri $baseURL"getUserToken" -Method POST -Body $authReqBody -UseBasicParsing | ConvertFrom-Json).userToken
$tagJson = $tagsToRead -join "','"
$reqBody = "{ 'userToken':'$userToken', 'tags': ['" + $tagJson + "'] }"
$tagData = (Invoke-WebRequest -Uri http://ourservice/api/v1/getTagData -Method POST -Body $reqBody -UseBasicParsing ).Content

$hashtable = @{}
(ConvertFrom-Json $tagData).psobject.properties | Foreach { $hashtable[$_.Name] = $_.Value }

$hashtableData = @{}
foreach ($prop in $hashtable['data'].PSObject.Properties)
{
	$hashtableData[$prop.Name] = $prop.Value[1]
}

Write-Host @"
<prtg>
<result>
<channel>Handles</channel>
<value>24</value>
</result>
<result>
<channel>clients</channel>
<unit>clients</unit>
<value>4</value>
</result>
<text>Hello</text>
</prtg>
"@

$revokeBody = "{ 'userToken':'$userToken' }"
$revokeResponse = Invoke-WebRequest -Uri http://ourservice/api/v1/revokeUserToken -Method POST -Body $revokeBody 

May, 2018 - Permalink