The numbers, paths, and limits.
Everything on this page is a specific, checkable fact with a source — binary paths, exact value ranges, character caps, port numbers, scope blast radius. Where NinjaOne does not publish a number, this page says so instead of inventing one.
01 · Agent on disk
Where the agent actually lives
The first thing to know when a script's custom-field write silently does nothing: the CLI is not on PATH, and it is not in the same place on every platform.
| OS | CLI binary | Field note |
|---|---|---|
| Windows | C:\ProgramData\NinjaRMMAgent\ninjarmm-cli.exe | Agent and Patcher services write logs plus policy, scripting, and JSON output here. First place to look when a script's custom-field write silently no-ops. |
| macOS | /Applications/NinjaRMMAgent/programdata/ninjarmm-cli | No .exe. Invoke by absolute path; the binary is not on PATH for script contexts. |
| Linux | /opt/NinjaRMMAgent/programdata/ninjarmm-cli | Must be prefixed with ./ when invoked from its own directory. Same argument grammar as Windows. |
02 · Command surface
ninjarmm-cli, completely
| Command | Syntax | Purpose |
|---|---|---|
help | ninjarmm-cli help | Print the command reference the agent actually supports on this build. |
get | ninjarmm-cli get <attribute> | Read a device custom field value. |
set | ninjarmm-cli set <attribute> <value> | Write a device custom field value. |
options | ninjarmm-cli options <attribute> | List valid values for a dropdown or multi-select. Use this instead of guessing GUIDs. |
templates | ninjarmm-cli templates [--ids|--names] | Enumerate documentation templates. |
documents | ninjarmm-cli documents "<template>" [--ids|--names] | Enumerate documents under a template. |
org-set | ninjarmm-cli org-set "<template>" "<document>" <field> "<value>" | Write an organization documentation field from an endpoint script. |
org-clear | ninjarmm-cli org-clear "<template>" "<document>" <field> | Clear an organization documentation field. |
Flags
| Flag | Effect | Example / caveat |
|---|---|---|
--stdin | Pipe input into a set | dir | ninjarmm-cli set --stdin fieldName |
--direct-out | Force stdout on Windows | May lose Unicode. Only reach for it when output is being swallowed by the normal channel. |
PowerShell: modern vs legacy
| Modern | Legacy | Why it matters |
|---|---|---|
Get-NinjaProperty [-Name] <String[]> [[-Type] <String>] [[-DocumentName] <String>] | Ninja-Property-Get $AttributeName | The modern form converts the value to the declared type. The legacy form hands back a raw string and is where most type bugs originate. |
Set-NinjaProperty | Ninja-Property-Set $AttributeName $Value | Both still function. Mixing the two across one script library is how field formats drift. |
— | Ninja-Property-Options $AttributeName | Resolve dropdown option GUIDs at runtime rather than hardcoding them. |
— | Ninja-Property-Clear $AttributeName | Clearing is a distinct operation. Setting an empty string is not the same thing. |
Exit codes
0 | Success |
1 | Error |
Two codes. There is no granular failure signal — if you need to know why a write failed you must capture stderr yourself.
Hard constraints
- PowerShell 1 and 2 are not supported.
- The CLI can only reach documentation templates that contain at least one populated field. An empty template is invisible to scripts.
- Secure (encrypted) documentation fields are write-only.
03 · Type system
Custom field types and their exact limits
This is the table that prevents most NinjaOne scripting bugs. The ranges are real: Numeric is a signed 32-bit integer, so a byte count on a modern volume overflows it.
| Type | Accepted format | Limit | Gotcha |
|---|---|---|---|
| CheckBox | 0, 1, true, false | Boolean only | Anything else is rejected. A PowerShell $true stringifies to 'True' — pass 1 or the lowercase literal. |
| Numeric | Integer | -2,147,483,648 to 2,147,483,647 | Signed 32-bit. Byte counts on large volumes overflow this — store GB, or use Decimal. |
| Decimal | Float | -9,999,999.999999 to 9,999,999.999999 | Six decimal places, seven integer digits. Locale-formatted numbers with a comma separator fail. |
| Text / TextMultiLine | String | 10,000 characters via CLI | Use a backtick-n for line breaks. Dumping raw command output here truncates silently at the cap. |
| TextEncrypted | String | 200 characters | Write-only for documentation fields. You cannot read it back to verify — log the fact of the write, not the value. |
| URL | Must start https:// | 200 characters | http:// is rejected. Long pre-signed URLs blow the 200-char cap. |
| TextEmail | RFC 5322 | [email protected] | Display-name forms ('Name <[email protected]>') are not accepted. |
| TextIpAddress | IPv4 or IPv6 | 192.168.1.100 | A single field, not a list. Multi-homed hosts need a Text field or one field per NIC. |
| TextPhone | E.164 | +1234567890 | Leading + required. Formatted US numbers with parentheses fail. |
| Date / DateTime / Time | Unix epoch seconds, or yyyy-MM-dd / yyyy-MM-ddTHH:mm:ss / HH:mm:ss | UTC only | No timezone offset is parsed. Convert local time to UTC before writing or every timestamp is wrong by your offset. |
| Dropdown | GUID or exact option name | Single selection | Exact name match. Resolve with `options` rather than hardcoding, because renaming an option breaks every script that hardcoded the string. |
| MultiSelect | Comma-separated GUIDs | Multiple selections | GUIDs, not names. This is the single most common cause of a silently empty multi-select. |
| Attachment / WYSIWYG | JSON object | Read-only | Cannot be written from a script. Plan documentation flows around this. |
04 · API
OAuth scopes and their blast radius
Scope selection is a security decision, not a configuration detail. Management scope can run scripts on endpoints — that is arbitrary code execution, and the client secret should be handled accordingly.
| Scope | Grants | Blast radius |
|---|---|---|
| Monitoring | Read-only access to monitoring data and organization structure. | Safe default for reporting, dashboards, CMDB sync, and any integration you did not write. |
| Management | Create and modify organizations and devices, run scripts. | This is arbitrary code execution on endpoints. Treat a Management-scoped client secret as a domain-admin-equivalent credential. |
| Control | Remote access via API. | Interactive session initiation. Separate it from Management; almost nothing needs both. |
| Protocol | OAuth 2.0 |
| Grant types | Authorization Code, Implicit, Client Credentials — Client Credentials is the server-to-server path. Restrict the app to it so an interactive flow can never be used. |
| Refresh token | Optional scope — Requested separately; without it a long-lived integration re-authenticates. |
| Configured at | Administration → Apps → API |
| Who can configure | System administrators only — A practical constraint on delegating integration work. |
What NinjaOne does not publish
NinjaOne does not publish rate limits, page-size caps, or regional base URLs on the open web; the interactive reference sits behind a tenant login. Third-party integrators consistently report per-endpoint throttling that requires batching and caching. Do not quote a specific rate-limit number to a customer — say it is per-endpoint, undocumented publicly, and must be measured in their tenant.
05 · Tools
Working tools, not diagrams
Three things you would otherwise do by hand in front of a customer: validate a field value before a script writes it, generate a firewall allowlist for a network team, and size patch rings against a real fleet.
Custom field format validator
Paste the value your script is about to write. Most "the field just stays empty" tickets are a format rejection, not a permissions problem.
Firewall allowlist builder
Generate a paste-ready list for a network team. Toggle wildcard support — if their firewall handles *.rmmservice.com the per-host list collapses dramatically.
# Wildcards (use these if your firewall supports them)
https://*.rmmservice.com
https://ninja-attachments.s3.us-west-2.amazonaws.com/*
# NinjaOne Remote
https://nc-[1-8]-us-west-2.ninjarmm.net
# Backup
https://ninja-backup-uswest1.s3.us-west-1.amazonaws.com
https://ninja-backup-uswest2.s3.us-west-2.amazonaws.com
https://ninja-backup-useast1.s3.us-east-1.amazonaws.com
https://ninja-backup-useast2.s3.us-east-2.amazonaws.com
# NMS agent
https://agent-app.ninjarmm.com
# IP gateways
52.33.253.235
34.212.188.161
35.163.67.164NinjaOne's canonical allowlist article requires a logged-in support account and returns 403 to anonymous fetches. The list above is reconciled from a partner mirror of that article and should be re-verified inside your own tenant before you hand it to a network team. Hostnames here are the US-West estate; EU, CA, and OC instances differ.
| Port | Use | Detail |
|---|---|---|
443/TCP | All normal traffic | TLS 1.2, Perfect Forward Secrecy, FIPS 140-2 validated modules. |
80/TCP | Initial connect, then redirect | The portal and API answer on 80 only to immediately redirect to 443. |
21/FTP, 80/HTTP | Third-party patch fallback | Some vendors only offer anonymous FTP/HTTP for update payloads; the agent may fall back after repeated 443 failures. Worth knowing before you tell a security team '443 only'. |
Patch ring planner
Enter a fleet size to get device counts per ring and a full-rollout duration you can defend in a change board.
| Ring | Share | Devices | Soak | Population |
|---|---|---|---|---|
| Ring 0 — canary | 1-2% | 24–48 | 24-48h | IT's own devices. If it breaks here, nobody files a ticket. |
| Ring 1 — pilot | 5-10% | 120–240 | 3-5 days | Volunteers across every hardware model and OS build you actually run. |
| Ring 2 — broad | 70-80% | 1680–1920 | 7 days | General population, business hours excluded. |
| Ring 3 — sensitive | 10-20% | 240–480 | after Ring 2 clears | Servers, executives, clinical or OT devices, anything with a change window. |
Ring 0 through Ring 2 clears in roughly 12days. A "patch within 72 hours" SLA is therefore incompatible with a real soak — say that out loud in the room rather than agreeing to both.
What NinjaOne actually documents
- Approval states: Auto, Manual, Reject
- Documented ring example: Ring 1 / Ring 2 / Ring 3 — Named as an example only. NinjaOne does not prescribe ring sizes.
- Only hard timing number: ≥ 1 hour between scan and install — The single numeric interval NinjaOne's ring guidance actually commits to.
What is field interpretation
NinjaOne's ring documentation deliberately gives no device percentages, no minimum soak duration, and no escalation criteria. If you present ring sizing to a customer, present it as your operating model, not as a NinjaOne recommendation. Saying 'the vendor does not prescribe this, here is what I would run and why' is more credible than inventing a spec.
Standard deployment-ring practice adapted from Microsoft's servicing-ring guidance. Defensible as an operating model; not a NinjaOne product claim. Adjust soak to the customer's incident-detection latency — a soak shorter than the time it takes users to report a problem is theatre.
Not an official source: NinjaOne's canonical allowlist article (ninjarmm.zendesk.com/hc/articles/211406886) requires an authenticated support account and returns HTTP 403 to anonymous requests, so it could not be cited directly. This is a partner's published mirror of that list. Treat the hostnames as a starting point and re-verify inside your own tenant before handing them to a network team.