Scripts that respect the platform's actual limits.

Every script here is built around a constraint documented on the reference page, and says which failure it prevents. The reference proves the limit is real; the script proves you can code against it.

Why these look paranoid

The traps are the design

Most NinjaOne scripting bugs are silent. A MultiSelect written with option names instead of GUIDs does not error — the field just stays empty. A byte count written to a Numeric field overflows a signed 32-bit integer and is rejected. A local timestamp written to a DateTime field is wrong by your UTC offset and nothing complains. The CLI returns exit code 0 or 1 and nothing else, so none of these announce themselves.

Each script below names the constraint it is built around and the specific failure it prevents. That is the difference between code that works on your machine and code you can hand to a customer.

13scripts
727lines, all syntax-checked
3languages · 4 platforms

13 of 13 shown

PowerShellWindows

Safe CLI wrapper with real error detail

Wrap every custom-field write so a failure tells you why, not just that it failed.

Built around
ninjarmm-cli exposes exit code 0 for success and 1 for error, and nothing else.
Prevents
Silent no-op writes. Without capturing stderr you cannot tell a rejected value format from a missing field, and both look identical to the calling script. Every other script here dot-sources this one.

Run it: Dot-source at the top of any other script. Invokes the CLI by absolute path, because it is never on PATH.

PowerShellWindows

Report free disk space without overflowing Numeric

Write free space and free percentage per fixed volume into custom fields.

Built around
Numeric custom fields are signed 32-bit: -2,147,483,648 to 2,147,483,647.
Prevents
Writing a raw byte count. A 4 TB volume is about 4x10¹² bytes — three orders of magnitude past the cap. The write is rejected, the field silently stays empty, and it reads as broken monitoring rather than a value that was too large.

Run it: Scheduled automation. Expects Numeric fields freeSpaceGb and freeSpacePct.

PowerShellWindows

Write a MultiSelect field without hardcoding GUIDs

Classify a device with several values, resolved from human-readable labels at runtime.

Built around
MultiSelect accepts comma-separated GUIDs only. Dropdown accepts a GUID or an exact option name.
Prevents
The single most common cause of a silently empty custom field — passing option NAMES to a MultiSelect. Hardcoding the GUIDs instead just trades one bug for another: it breaks the moment somebody renames an option.

Run it: Pass labels; the script resolves them via Ninja-Property-Options and fails loudly on a mismatch.

PowerShellWindows

Write a timestamp that is not silently wrong

Stamp a DateTime custom field with the moment a check completed.

Built around
Date, DateTime and Time fields take epoch seconds or yyyy-MM-ddTHH:mm:ss, interpreted as UTC. No offset is parsed.
Prevents
Writing local time. Get-Date returns local; nothing errors; every timestamp is quietly wrong by your UTC offset. That is exactly why the bug survives to production.

Run it: Call at the end of any automation. Writes epoch seconds because they are unambiguous.

PowerShellWindows

Turn encryption state into monitored evidence

Record real BitLocker protection state and whether a recovery key actually exists.

Built around
BitLocker Status is a condition covering enabled, disabled, locked and unlocked, with volume exclusions.
Prevents
Reporting 'encrypted' from the image build. A volume can be fully encrypted with protection SUSPENDED and still look encrypted — and an encrypted machine with no escrowed key is an unrecoverable machine.

Run it: Requires elevation. Writes a CheckBox and a Text summary; exits non-zero when non-compliant.

PowerShellWindows

Find endpoints running more than one antivirus

Detect competing real-time engines on a single endpoint.

Built around
Antivirus Health detects missing, disabled, outdated AND multiple antivirus products.
Prevents
Two failures at once: assuming one AV per machine, and returning a false clean on a server. SecurityCenter2 is client-SKU only, so on a server this reports that it could not evaluate rather than that everything is fine.

Run it: Read-only. Good first-call discovery finding in a POC.

PowerShellWindows

Detect a genuinely pending reboot

Report whether the endpoint is waiting on a restart, why, and for how long.

Built around
Reboot Pending is a condition that can trigger on duration since the flag was set, or on user idle time.
Prevents
Checking one registry location. CBS, Windows Update, pending file rename and pending computer rename are set independently — check one, return false, and patch compliance drifts silently while the fix is not actually in effect.

Run it: Read-only. Pairs with the Reboot Pending condition to age the finding.

PowerShellWindows

Bounded, reversible service remediation

Restart a service that should be running — once — and record the outcome.

Built around
Windows Service conditions alert on up, down and exists, with a configurable start-alerting delay.
Prevents
Unbounded remediation. It tries once, refuses to start a service set to Disabled because somebody chose that deliberately, and writes evidence either way. That is what makes it defensible to a change board.

Run it: Pass -ServiceName. Intended to be triggered by a Windows Service condition.

PowerShellWindows

Audit local administrators

Report who holds local admin so privilege drift becomes visible.

Built around
Text custom fields cap at 10,000 characters through the CLI.
Prevents
Two traps. Get-LocalGroupMember throws on orphaned SIDs from deleted domain accounts — the members you most want to find — so this uses ADSI. And it trims deliberately, because an over-length write is rejected rather than truncated.

Run it: Read-only. Strong first-call finding alongside the multiple-AV check.

BashmacOS

FileVault state on macOS

Record FileVault protection state and institutional recovery key presence.

Built around
FileVault Status is a condition with a duration threshold. The macOS CLI lives at /Applications/NinjaRMMAgent/programdata/ninjarmm-cli.
Prevents
Assuming the Windows path, or that the CLI is on PATH. On macOS it is neither, and there is no .exe. Also checks the recovery key, because on/off alone is half the answer.

Run it: sudo ./filevault-status.sh — writes a CheckBox and a Text summary, exits non-zero when unprotected.

BashLinux

Daemon health on Linux

Check that required daemons are active and report the ones that are not.

Built around
Daemon is a distinct Linux condition with alert delay and auto-reset. The Linux CLI lives at /opt/NinjaRMMAgent/programdata/ninjarmm-cli.
Prevents
Treating Linux like Windows, and reporting a false pass. systemctl is not on every distribution, so on a non-systemd host this says so and exits rather than claiming everything is healthy.

Run it: ./check-daemons.sh sshd nginx postgresql — exits non-zero if anything is down.

JavaScriptCross-platform

Page the device list with correct scope and backoff

Authenticate with client credentials and page every device into a summary.

Built around
OAuth 2.0 client credentials is the server-to-server grant. Monitoring scope is read-only.
Prevents
Requesting Management scope for a read-only job — that scope can run scripts on endpoints, which is arbitrary code execution. And inventing a rate limit: none is published, so it honours 429 with Retry-After instead of guessing.

Run it: NINJA_CLIENT_ID and NINJA_CLIENT_SECRET in the environment, then node devices-report.mjs

JavaScriptCross-platform

Find devices that stopped checking in

List endpoints silent for longer than a threshold, with the date they were last seen.

Built around
Monitoring scope is sufficient. Device Down is a condition with a reset interval and re-trigger option.
Prevents
A dishonest denominator. Compliance percentages are computed over devices that answered, so machines that went silent are excluded — and the number improves as devices fall off the network.

Run it: node stale-agents.mjs 14