Configure a Custom Script Check
Run your own PowerShell or bash script as a monitoring check, set a result status, and surface the values in the dashboard.
Written By Erdinc Akay
Last updated 26 days ago
A custom script check runs a script you write — PowerShell on Windows, bash on Linux and macOS — at a fixed interval and reports a result back to octoja. Use it when none of the built-in checks match what you need to monitor. You build the check once under Configuration → Custom Checks; afterwards it appears alongside the built-in checks when you assign checks to a device.
Before you start
- You need the Custom Check Management permission to build the check.
- Assigning the check to a device (step 10) additionally requires the Monitoring Check Management permission.
- You need a target device with the agent installed and connected.
- On Linux,
jqmust be installed on the target device — the agent's script wrapper uses it to read parameters and serialize output. On macOS, the wrapper usespython3, which is preinstalled on macOS. - Any other tool your script invokes (for example
awk,bc) must also be installed on the target device — the agent does not bundle script-side dependencies.
Steps
- Go to Configuration → Custom Checks in the sidebar.
- Click New Custom Check.
- Fill in the create dialog — Check ID (a unique kebab-case identifier, e.g.
disk-temperature; it cannot be changed later), Name (English), and Name (German). Optionally pick an existing custom check under Clone from to start from a copy. Click Create Check. - On the General tab, leave Mode set to Advanced script (the alternative, Simple SNMP, swaps the script tabs for an SNMP probe editor and is out of scope for this how-to). Set the description, icon, category, tags, and the check Interval in minutes — default 5, allowed range 5–1440.
- Open the Script tab. For each platform you want to support (Windows / Linux / macOS), paste your script — examples below. Platforms without a script are not available for assignment. Write only your check logic: the agent automatically wraps the script with the input/output handling.
- Open the Parameters tab and define any input parameters your script needs (key, type, labels, required, default value). These appear as configurable fields when the check is assigned to a device.
- Open the Output Schema tab and declare the fields your script writes — key, type, unit, and label. The Detail Layout and History Layout tabs let you arrange how those fields render on the device's Checks tab.
- Open the Test tab, select a connected device, and click Run Test. You see the result, exit code, runtime, the script's output and errors, and the parsed output fields — without waiting for a check interval.
- Click Save.
- Assign the check: go to Devices, open the target device, click the Checks tab → Add Check, pick your custom check (it appears alongside the built-in checks), fill in the parameters you defined, and click Add Check.
Setting the result
Your script reports its status by setting checkResult in the output — $output.checkResult in PowerShell, set_result in bash. It starts at 0 (OK), so a script that sets nothing reports OK. The agent maps the value like this:
Note: you can also set the status by name instead of by number: $output.checkResult = "Critical" (PowerShell) or set_result Critical (bash) — the agent accepts the status names Success, Warning, Critical, and Failure.
How the agent runs your script
You don't need these details to build a check, but they explain what to expect:
- The agent downloads your script from the web service with the input/output wrapper already added, stores it as a file, and runs it with
powershell -ExecutionPolicy Bypass -Fileon Windows orbashon Linux and macOS. - The parameters configured at assignment are passed to the script on standard input; you read them through
$checkInput(PowerShell) orget_input(bash). - The status comes from the
checkResultvalue in your output — not from text your script prints and not from the exit code. Anything else written to stdout is ignored. - A non-zero exit code makes the check report Failure, regardless of what the output says.
- Each run has a fixed time limit of 5 minutes (not configurable). A script that runs longer is stopped and the check reports Failure.
- Output larger than 16 KB keeps its status, but the field values are dropped and the result is marked as truncated.
The full input, output, and helper contract is documented in the Custom Script Check Reference linked below.
PowerShell (Windows)
The wrapper exposes $checkInput (the parsed input parameters) and $output (a hashtable pre-filled with checkResult = 0). Write your results into $output. Note: the variable is $checkInput, not $input — $input is a reserved PowerShell automatic variable.
# Read an input parameter (defined on the Parameters tab)$threshold = $checkInput.threshold# Do your work$cpuLoad = (Get-Counter '\Processor(_Total)\% Processor Time').CounterSamples.CookedValue# Write outputs into $output$output["cpuLoad"] = [math]::Round($cpuLoad, 1)if ($cpuLoad -ge $threshold) { $output["checkResult"] = 2 # Critical $output["message"] = "CPU load $cpuLoad% exceeds threshold $threshold%"} elseif ($cpuLoad -ge ($threshold * 0.8)) { $output["checkResult"] = 1 # Warning} else { $output["checkResult"] = 0 # OK}Bash (Linux)
The wrapper provides three helpers (all of them need jq on the device):
get_input "key"— read an input parameter.set_output "key" value— set an output field.set_result 0|1|2— shortcut forcheckResult(0 = OK, 1 = Warning, 2 = Critical).
THRESHOLD=$(get_input "threshold")LOAD=$(uptime | awk -F'load average:' '{print $2}' | awk -F',' '{print $1}' | xargs)set_output "loadAverage" "$LOAD"if (( $(echo "$LOAD > $THRESHOLD" | bc -l) )); then set_result 2 # Critical set_output "message" "Load average $LOAD exceeds threshold $THRESHOLD"else set_result 0 # OKfiBash (macOS)
On macOS the agent uses a separate wrapper that provides the same helpers — get_input, set_output, set_result — but builds on python3 (preinstalled on macOS) instead of jq, and avoids bash features that are unavailable in the macOS-bundled bash 3.2. Your script code looks the same as the Linux example above.
If you do not provide a macOS-specific script, the agent runs your Linux script on macOS. That works for portable bash but fails the moment you depend on a Linux-only tool.
What not to do
Troubleshooting
The check shows Failure with an error message. The script exited with a non-zero exit code, threw an error, or a wrapper dependency is missing on the device — jq on Linux (apt install jq, dnf install jq), python3 on macOS. Run the script from the editor's Test tab: the error output appears there directly.
The check shows OK when you expected Warning or Critical. You probably forgot to set $output["checkResult"] (PowerShell) or call set_result (bash) — the default is 0 / OK. Also double-check the values: 1 is Warning and 2 is Critical.
The check reports Failure after running for a long time. The script exceeded the fixed 5-minute limit. The limit cannot be raised — make the script faster or split it into multiple smaller checks.
The dashboard shows the status but no values. The field keys your script writes must match the keys declared on the Output Schema tab, and very large outputs (above 16 KB) are truncated to the status only.
How to verify the check is running
The fastest way is the editor's Test tab: select a connected device and click Run Test to see the result, exit code, runtime, output, and parsed fields immediately. After you assign the check to a device, octoja runs it at the configured interval — open the Checks tab on the device to see the result rendered with the layout you defined. If the check produces no result there, check the agent log on the device for script errors.
Related articles
- Custom Script Check Reference — the full input, output, and helper reference.