Datto RMM → Breeze
Datto RMM (formerly CentraStage) is one of the easier migrations. Its API is clean and well-documented, its Components are ordinary PowerShell and bash with an environment-variable wrapper, and its job engine is a reliable way to push the Breeze agent.
The two things that need real thought are UDFs and the flat site model.
Read Migrating to Breeze first — this page only covers the Datto-specific parts.
Hierarchy Mapping
Section titled “Hierarchy Mapping”Datto RMM is flat: an account contains Sites, and a Site contains Devices. There is no client-above-site layer, so most MSPs use one Datto site per customer.
| Datto RMM | Breeze | Notes |
|---|---|---|
| Account | Partner | Your MSP tenant. |
| Site | Organization | One Breeze org per Datto site. |
| — | Site | Create one site per org (name it Main) unless the customer genuinely has multiple locations. |
| Device Group / filter | Device Group | Datto’s saved device filters map to Breeze dynamic device groups. |
| Device | Device |
Phase 0 — Export from Datto
Section titled “Phase 0 — Export from Datto”Datto RMM’s API v2 is at https://<zone>-api.centrastage.net/api/v2, where <zone> matches your web console (concord, merlot, pinotage, syrah, vidal, zinfandel). Create an API key under Setup → Users → your user → API Access, which yields an API key and secret key.
-
Get a token (OAuth2 password grant, with the fixed public client):
Terminal window ZONE=merlotTOKEN=$(curl -sf -u 'public-client:public' \-X POST "https://$ZONE-api.centrastage.net/auth/oauth/token" \-d 'grant_type=password' \--data-urlencode "username=$DATTO_API_KEY" \--data-urlencode "password=$DATTO_SECRET_KEY" | jq -r .access_token) -
Export the site list — this becomes your Breeze organization list:
Terminal window curl -sf -H "Authorization: Bearer $TOKEN" \"https://$ZONE-api.centrastage.net/api/v2/account/sites?max=250" \| jq -r '.sites[] | [.name, "Main"] | @csv' > tree.csvsed -i '1i organization,site' tree.csvFeed
tree.csvstraight into Recipe 1. -
Export devices per site — your reconciliation checklist and your license clean-up list:
Terminal window for uid in $(curl -sf -H "Authorization: Bearer $TOKEN" \"https://$ZONE-api.centrastage.net/api/v2/account/sites?max=250" | jq -r '.sites[].uid'); docurl -sf -H "Authorization: Bearer $TOKEN" \"https://$ZONE-api.centrastage.net/api/v2/site/$uid/devices?max=500" \| jq -r --arg s "$uid" '.devices[] |[$s, .hostname, .operatingSystem, .deviceType.category, .lastSeen, .online] | @tsv'done > datto-devices.tsv -
Export UDFs. Datto gives every device 30 user-defined fields (
udf1…udf30), and they are usually load-bearing — warranty dates, asset tags, install dates.GET /api/v2/device/{uid}returns them underudf. Dump them before you lose access:Terminal window curl -sf -H "Authorization: Bearer $TOKEN" \"https://$ZONE-api.centrastage.net/api/v2/device/$DEVICE_UID" | jq '{hostname, udf}'
Phase 3 — Deploy the Breeze Agent with a Datto Component
Section titled “Phase 3 — Deploy the Breeze Agent with a Datto Component”This is the fastest part of the migration and the reason to keep Datto running until the end.
-
Create a component. In Datto RMM go to Automation → Components → New Component, category Scripts, and add two variables so one component serves every site:
Variable Type Purpose BreezeServerValue https://breeze.yourdomain.comBreezeKeyValue The per-site enrollment key from Recipe 2 BreezeSecretValue Your AGENT_ENROLLMENT_SECRET, if configuredDatto exposes component variables to the script as environment variables of the same name.
-
Paste the script. Use the Windows PowerShell payload from Recipe 3, reading the variables from the environment:
Terminal window $Server = $env:BreezeServer$Key = $env:BreezeKey$Secret = $env:BreezeSecretDatto components run as SYSTEM, so no elevation wrapper is needed.
-
Add antivirus exclusions first. Push the Breeze AV exclusions — and add Datto’s own paths to any Breeze-managed AV policy — before the enrollment job. Two RMM agents each running a watchdog is a well-known trigger for behavioural detections.
-
Run it as a scheduled job, not a quick job. Create a Job targeting one site, scheduled daily for the length of your rollout window. The
agent.yamlexistence check makes re-runs a no-op, so the daily schedule quietly sweeps up laptops that were offline on the first pass. A one-shot Quick Job typically reaches 85–92% of a fleet; a two-week daily job reaches 98%+. -
Roll in waves. Pilot site → 10% of sites → the rest.
Migrating Components
Section titled “Migrating Components”Datto Components are ordinary scripts with a variable wrapper, so the bodies port with minimal edits.
| Datto concept | Breeze equivalent |
|---|---|
Component variables ($env:VarName) |
Script parameters |
| stdout → job output | Script output, captured per execution |
Exit code 0 = success |
Same, plus exitCodeSeverityMapping to raise alerts by exit code |
Write-Host '<-Start Result->…' UDF writes |
Breeze custom fields |
| ComStore components | Check the Breeze system script library first |
The one genuine rewrite is Datto’s result-to-UDF convention — components that emit <-Start Result->key=value<-End Result-> to write back into a UDF. In Breeze, write to a custom field via the API from within the script instead.
Import the converted bodies in bulk with Recipe 6. Set availability: "partner" so one copy serves every customer.
Migrating UDFs
Section titled “Migrating UDFs”- Decide which of
udf1…udf30are actually populated — usually 3 to 6 of them. Dump all thirty across a sample of 50 devices and count non-empty values. - Create matching Breeze custom fields with real names and types. This is the moment to stop calling it
udf7. - Backfill by joining your Datto per-device UDF export against Breeze devices on hostname, then
POSTthe values via the device custom-field-values endpoint — one of the few surfaces that does accept anX-API-Key.
Monitors and Alerting
Section titled “Monitors and Alerting”Datto monitors live inside Policies, one monitor type per policy, targeted by site or device filter. Breeze splits this differently: monitors define what is measured and alert rules define when it fires and who hears about it.
Do not port one-for-one. Export your last 90 days of Datto alerts, sort by volume, and rebuild only what actually generated action. The top three alert types on most Datto fleets are disk space, offline, and patch failure — start there, and define them partner-wide so they apply to every organization at once.
Re-point ticketing at the same time: connect your PSA to Breeze via PSA integrations, then disable Datto’s PSA integration for that site so you are not double-ticketing.
Phase 6 — Decommission the Datto Agent
Section titled “Phase 6 — Decommission the Datto Agent”Only after Recipe 4 shows zero unexplained gaps for that site.
-
Disable alerting in the Datto policies bound to that site. Leave the agent installed.
-
Wait one full patch cycle — a month. This is where you find the monitor you forgot.
-
Uninstall via Datto itself, using the ComStore Agent Removal component, or a script step:
Terminal window & "${env:ProgramFiles(x86)}\CentraStage\uninst.exe" /SOn macOS, run Datto’s supplied
uninstall.shfrom/usr/local/share/CentraStage/. -
Verify from Breeze, not from Datto. Run Recipe 5 — Breeze’s Management Posture fingerprints Datto RMM directly, so it reports machines whose Datto agent was already broken and therefore invisible in the Datto console. Drive the count to zero.
-
Delete the site in Datto and reduce your licence count. Export anything you are contractually required to retain first — site deletion is irreversible.