Three tools, in the order you typically reach for them: the doctor finds script
mistakes without running anything, -DryRun shows the sensor result as objects in
your console, and file logging captures what happens on the probe where you cannot
watch. Logging has its own page; this one covers the doctor and -DryRun.
Invoke-PrtgSensorDoctor analyzes a sensor script (it parses, never executes) and checks
for the classic mistakes: Restart-* in the wrong place, manual output calls inside the
Invoke-PrtgSensor block, a leftover -DryRun, web requests without TLS setup, output
after the sensor response, unsafe file encoding, and more. On Windows it also probes
whether PrtgSensorKit and your imported modules are actually installed in the hosts the
sensor runs in (32-bit PowerShell 5.1, 64-bit, pwsh).
Invoke-PrtgSensorDoctor -ScriptPath 'C:\...\Custom Sensors\EXEXML\MySensor.ps1'A colored summary is printed to the console, and every check comes back as an object
(CheckId, Severity, Message, Line, Recommendation) for scripted use:
$findings = Invoke-PrtgSensorDoctor -ScriptPath .\MySensor.ps1 -SkipEnvironmentChecks
$findings | Where-Object Severity -eq 'Error'See 21-sensor-doctor.ps1.
-DryRun runs the block exactly like a real run but returns the result as a PowerShell
object instead of the PRTG JSON string, so you can inspect channels and message without
reading JSON. Errors are rethrown with full details instead of being flattened into a PRTG
error response.
# In a normal console:
$result = .\MySensor.ps1 # the script calls Invoke-PrtgSensor -DryRun { ... }
$result.prtg.result | Format-Table
$result.prtg.textWarning
Remove -DryRun before deploying: a deployed dry run does not emit valid PRTG JSON.
The doctor catches a leftover -DryRun (check PSK0010).
Console testing can lie: PRTG runs the script in 32-bit 5.1, as the probe account, with a
different working directory. When a sensor works in your console but fails deployed, add
-EnableLogging and read the run log from the probe - see File logging.
For secrets that fail only at runtime, see the account-binding note in
Credentials and secrets.
Sensor messages, PRTG error text, and Write-PrtgLog lines are masked for the secret values the
module knows about - resolved PRTG credential placeholders and Get-PrtgSecret -AsPlainText
values. A leaked credential shows up as abc-de***** rather than in full, which is usually
enough to tell which credential got into the message.
Two things to keep in mind while debugging:
-DryRunis not masked. It rethrows the originalErrorRecordso you get the real error on the console, which is the point. That path never reaches PRTG.- Masking is a safety net, not a guarantee. Only exact substring matches are found, and
Set-PrtgOutput,Write-PrtgOutput, channel names, and channel values are not covered. The full list of limitations is in Credentials and secrets.
If a value you expected to be masked shows up in full, the usual cause is that "Set placeholders as environment values" is not enabled on the sensor, so the module never saw the credential.