ConnectWise Automate → Breeze
ConnectWise Automate (formerly LabTech) is the most expensive migration in this section, and it is worth being honest about why: its scripts, internal monitors, and remote monitors are all proprietary step-based objects with no export path into anything else. None of them port. Everything else — the client tree, the computer list, the EDFs — moves fine.
Plan for re-authoring, not converting. In exchange, most MSPs find that a decade of accumulated Automate scripting compresses into a fraction of its original size.
Read Migrating to Breeze first.
Hierarchy Mapping
Section titled “Hierarchy Mapping”| Automate | Breeze | Notes |
|---|---|---|
| Automate instance | Partner | |
| Client | Organization | Direct match. |
| Location | Site | Direct match. Automate always creates a default location per client. |
| Computer group (static/auto-join) | Device Group | Auto-join groups map to Breeze dynamic device groups. |
| Computer | Device | |
| Contact | — | Breeze cannot create contacts programmatically today; enter them by hand or keep them in your PSA. |
Phase 0 — Export from Automate
Section titled “Phase 0 — Export from Automate”You have two routes. The REST API is the supported one; direct SQL against the labtech MySQL database is faster and far more complete, and is what most migration projects actually use for a bulk export. Use SQL for the export, and the API for anything you need to write back.
Option A — Direct SQL (recommended for export)
Section titled “Option A — Direct SQL (recommended for export)”-- Client → Location tree, ready for Recipe 1SELECT c.Name AS organization, l.Name AS siteFROM clients cJOIN locations l ON l.ClientID = c.ClientIDWHERE c.Name NOT IN ('Deleted Clients')ORDER BY c.Name, l.Name;-- Device inventory + last-contact, for reconciliation and licence cleanupSELECT c.Name AS client, l.Name AS location, comp.Name AS hostname, comp.OS, comp.LastContact, DATEDIFF(NOW(), comp.LastContact) AS days_staleFROM computers compJOIN clients c ON c.ClientID = comp.ClientIDJOIN locations l ON l.LocationID = comp.LocationIDORDER BY days_stale DESC;-- EDFs (Extra Data Fields) at computer scopeSELECT comp.Name AS hostname, ef.Name AS field, ed.ValueFROM extradatavalues edJOIN extrafield ef ON ef.ID = ed.ExtraFieldIDJOIN computers comp ON comp.ComputerID = ed.ExtraDataIDWHERE ed.EDFType = 2 AND ed.Value <> '';Export to CSV, reshape to organization,site, and feed Recipe 1.
Option B — REST API
Section titled “Option B — REST API”Automate’s REST API lives at https://<your-automate>/cwa/api/v1, authenticated by POST /apitoken with an Automate username and password (and a two-factor code where enforced).
TOKEN=$(curl -sf -X POST "https://$AUTOMATE/cwa/api/v1/apitoken" \ -H 'Content-Type: application/json' \ -d "{\"UserName\":\"$USER\",\"Password\":\"$PASS\"}" | jq -r .AccessToken)
curl -sf -H "Authorization: Bearer $TOKEN" \ "https://$AUTOMATE/cwa/api/v1/Clients?pageSize=1000" | jq -r '.[] | [.Id,.Name] | @tsv'curl -sf -H "Authorization: Bearer $TOKEN" \ "https://$AUTOMATE/cwa/api/v1/Computers?pageSize=1000" \ | jq -r '.[] | [.Client.Name, .Location.Name, .ComputerName, .OperatingSystemName, .LastContact] | @tsv'Phase 3 — Deploy the Breeze Agent with an Automate Script
Section titled “Phase 3 — Deploy the Breeze Agent with an Automate Script”-
Create a script. In the Automate Control Center: Automation → Scripts → New Script, script type Computer Script. You need exactly one function — a
Script Execute/Shellstep that runs PowerShell as SYSTEM (LTService already runs as SYSTEM, so no elevation is needed). -
Use a script parameter for the key. Define a
@breezekey@script parameter and pass the per-location enrollment key from Recipe 2 when scheduling. Alternatively store the key in a location-level EDF and read it with@edf(...)@so one script serves every client. -
Body: the Windows PowerShell payload from Recipe 3. Keep the
agent.yamlexistence check — it is what makes the scheduled re-runs safe. -
Add AV/EDR exclusions in both directions before the push — see Antivirus Exceptions.
-
Schedule against a group, daily. Create an auto-join group for the target client and schedule the script daily for the length of your rollout window. This picks up machines that were offline, and — importantly for Automate estates — retries against machines where LTService is wedged and recovers on its next check-in.
Scripts: Plan to Re-author
Section titled “Scripts: Plan to Re-author”Automate scripts are step lists stored in the database and exported as proprietary XML. There is no converter, and building one is not a good use of the migration budget.
The practical approach:
-
Rank by actual use. Query what has actually run:
SELECT s.ScriptName, COUNT(*) AS runs, MAX(sl.DateRan) AS last_runFROM scriptlogs sl JOIN scripts s ON s.ScriptId = sl.ScriptIdWHERE sl.DateRan > DATE_SUB(NOW(), INTERVAL 12 MONTH)GROUP BY s.ScriptName ORDER BY runs DESC; -
Delete the tail. Anything with zero runs in 12 months does not migrate. On a typical Automate estate this removes 70–85% of the library.
-
Check the Breeze system library (
GET /scripts/system-library) before re-authoring anything. Disk cleanup, service restart, printer spooler, profile cleanup, reboot-required checks — the standard Automate toolkit is largely already there. -
Re-author what remains as plain PowerShell or bash. Scripts whose steps were
Shell,Execute Script, orFile Downloadtranslate almost mechanically; scripts built fromIf/Thenstep logic against Automate’s own database do not translate at all and should be reconsidered rather than reproduced. -
Bulk-load with Recipe 6,
availability: "partner".
Monitors
Section titled “Monitors”Automate has two kinds and neither ports:
- Internal monitors are SQL queries against the Automate database. They have no meaning outside Automate. Re-express the intent as Breeze monitors and alert rules.
- Remote monitors are agent-side checks (service state, performance counter, event log, drive space). These map well onto Breeze’s equivalents — service monitoring, event log forwarding, and disk thresholds.
Rank by alert volume over the last 90 days and rebuild the top of the list partner-wide. Automate estates typically carry hundreds of monitors of which a dozen generate every ticket that mattered.
EDFs → Custom Fields
Section titled “EDFs → Custom Fields”Map computer-scope EDFs to Breeze custom fields, and client/location-scope EDFs to organization-level fields or your PSA. Backfill by joining the EDF export against Breeze devices on hostname.
Phase 6 — Decommission LTService
Section titled “Phase 6 — Decommission LTService”Only after Recipe 4 is clean for that client.
-
Disable alerting — remove the client’s computers from monitor targets. Leave the agent installed.
-
Wait one full patch cycle.
-
Uninstall via Automate. Use the built-in Agent Uninstall script, or run ConnectWise’s
Agent_Uninstall.exefrom the LTSVC directory:Terminal window $u = "$env:windir\LTSvc\Agent_Uninstall.exe"if (Test-Path $u) { Start-Process $u -Wait }Automate agents are notoriously persistent. If the standard uninstaller leaves remnants, ConnectWise’s own
LabTechUninstaller/Agent_Uninstallcleanup routine removes theLTServiceandLTSvcMonservices,%windir%\LTSvc, and theHKLM\SOFTWARE\LabTechkeys. -
Verify from Breeze. Recipe 5 — Breeze Management Posture fingerprints both ConnectWise Automate and ScreenConnect independently, so it will tell you if the remote-access component survived the RMM uninstall. That distinction matters: leftover ScreenConnect is an unmanaged remote-access path into your customers’ networks.
-
Delete the client in Automate and reduce your agent count.