NinjaOne → Breeze
NinjaOne is the cleanest migration of any RMM in this section. Its hierarchy maps onto Breeze’s one-for-one, its API is a well-behaved OAuth2 REST API, and its scripts are plain PowerShell and shell. Most of the effort goes into policy inheritance, which has no direct Breeze equivalent and generally simplifies on the way across.
Read Migrating to Breeze first.
Hierarchy Mapping
Section titled “Hierarchy Mapping”| NinjaOne | Breeze | Notes |
|---|---|---|
| Instance | Partner | |
| Organization | Organization | Direct match. |
| Location | Site | Direct match, including the “Main Office” default. |
| Device role / group | Device Group | Ninja’s device roles map well to Breeze dynamic device groups. |
| Device | Device |
This is as close to a lift-and-shift as RMM tenancy gets.
Phase 0 — Export from NinjaOne
Section titled “Phase 0 — Export from NinjaOne”Create an API client under Administration → Apps → API, with grant type Client Credentials and the monitoring and management scopes. Your region determines the host — app.ninjarmm.com (US), eu.ninjarmm.com, oc.ninjarmm.com, ca.ninjarmm.com.
-
Get a token:
Terminal window HOST=app.ninjarmm.comTOKEN=$(curl -sf -X POST "https://$HOST/ws/oauth/token" \-d grant_type=client_credentials \-d "client_id=$NINJA_CLIENT_ID" \-d "client_secret=$NINJA_CLIENT_SECRET" \-d 'scope=monitoring management' | jq -r .access_token) -
Export the org → location tree. This is your Breeze tenancy CSV, produced directly:
Terminal window curl -sf -H "Authorization: Bearer $TOKEN" "https://$HOST/v2/organizations" > orgs.jsoncurl -sf -H "Authorization: Bearer $TOKEN" "https://$HOST/v2/locations" > locs.jsonecho 'organization,site' > tree.csvjq -r --slurpfile o orgs.json '.[] as $l | ($o[0][] | select(.id == $l.organizationId)) as $org| [$org.name, $l.name] | @csv' locs.json >> tree.csvFeed it to Recipe 1.
-
Export devices — your reconciliation checklist:
Terminal window curl -sf -H "Authorization: Bearer $TOKEN" \"https://$HOST/v2/devices-detailed" \| jq -r '.[] | [.organizationId, .locationId, .systemName,.nodeClass, .offline, .lastContact] | @tsv' > ninja-devices.tsv -
Export custom fields. Ninja custom fields exist at global, organization, location and device scope. Dump the device-scoped values, which are the ones that usually matter:
Terminal window curl -sf -H "Authorization: Bearer $TOKEN" \"https://$HOST/v2/queries/custom-fields" | jq . > ninja-custom-fields.json -
Export policies for reference:
GET /v2/policies. You are not going to import these, but you need them open in a second window while you rebuild.
Phase 3 — Deploy the Breeze Agent with a Ninja Script
Section titled “Phase 3 — Deploy the Breeze Agent with a Ninja Script”-
Create the script. Administration → Library → Automation → Create → PowerShell, run as System. Use the Windows payload from Recipe 3.
Ninja passes script variables as parameters, so parameterise the enrollment key rather than hardcoding it:
Terminal window param([string]$Server = 'https://breeze.yourdomain.com',[string]$Key,[string]$Secret)You can also read a Ninja custom field with
Ninja-Property-Get, which lets you store the per-location enrollment key as an organization custom field and have one script resolve it automatically. That is the tidiest approach if you have more than a handful of customers. -
Add AV/EDR exclusions first — both directions. See Antivirus Exceptions.
-
Schedule it, don’t run it once. Create a Scheduled Task targeting one organization, running daily. The
agent.yamlcheck makes it idempotent, so it sweeps up offline laptops over the following days. A single manual run reliably misses 8–15% of a fleet. -
Roll in waves. Pilot org → 10% → the rest.
Migrating Scripts
Section titled “Migrating Scripts”Ninja’s automation library is PowerShell, batch, and shell, so bodies port directly. Rewrite the wrapper:
| NinjaOne | Breeze |
|---|---|
Script parameters / $env: variables |
Script parameters |
Ninja-Property-Get / Ninja-Property-Set |
Custom field reads/writes via the API |
Exit code 0 = success |
Same, plus exitCodeSeverityMapping for severity by exit code |
| Run As: System / Logged-on user | runAs: "system" / "user" |
| Script categories | category field |
The only real work is Ninja-Property-Get / Ninja-Property-Set, which have no drop-in replacement — replace with an authenticated call to the Breeze device custom-field-values endpoint.
Bulk-load the converted scripts with Recipe 6, setting availability: "partner".
Policies: The Part That Needs Design
Section titled “Policies: The Part That Needs Design”This is where NinjaOne migrations take their time. Ninja uses nested, inheriting policies — a parent policy with child overrides per organization or device role. Breeze does not model inheritance that way. Instead it is partner-wide first: a policy is owned by the partner and applies across every organization, or it is owned by one organization.
The translation:
| NinjaOne | Breeze |
|---|---|
| Base policy applied everywhere | Partner-wide configuration policy |
| Per-role child policy (Workstation / Server) | Separate partner-wide policy bound to a dynamic device group by role |
| Per-organization override | Organization-owned policy |
| Policy conditions → alerts | Monitors + alert rules |
| Patching section of a policy | Patch policies and update rings |
Phase 6 — Decommission NinjaRMMAgent
Section titled “Phase 6 — Decommission NinjaRMMAgent”Only after Recipe 4 is clean for that organization.
-
Disable alerting on the Ninja policies bound to that org; leave the agent installed.
-
Wait one full patch cycle.
-
Uninstall via Ninja. The supported path is to delete the device in the Ninja console, which triggers agent removal. To do it by script:
Terminal window $p = Get-CimInstance Win32_Product | Where-Object { $_.Name -like 'NinjaRMMAgent*' }if ($p) { msiexec /x $p.IdentifyingNumber /qn /norestart }On macOS, run Ninja’s
/Applications/NinjaRMMAgent/uninstall.sh. -
Verify from Breeze. Recipe 5 — Breeze Management Posture fingerprints NinjaOne. Drive the count to zero. This catches the machines whose Ninja agent was already dead and which the Ninja console therefore cannot report on.
-
Remove the organization in Ninja and reduce your licence count, after exporting anything you must retain.