Identity Azure

Migrating from Entra Connect Sync to Entra Cloud Sync: A Step-by-Step Cutover Guide

Entra Connect Sync (formerly Azure AD Connect) has carried hybrid identity for a decade, but Microsoft has made the direction clear: Cloud Sync is the strategic agent, and from July 2026 tenants whose use cases are fully covered will start receiving migration notices via the M365 Message Center and Connect Health. This guide is the cutover I run for production forests — a side-by-side coexistence model where you hand objects over in scoped batches rather than flipping one switch and praying.

The most important fact to internalize before you touch anything: moving an object out of Connect Sync scope deletes its cloud representation. Users are soft-deleted (recoverable for 30 days), but groups are hard-deleted. The entire coexistence design below exists to prevent that deletion during the handoff.

1. Connect Sync vs Cloud Sync: know the gaps before you commit

Cloud Sync is not “Connect Sync, but lighter.” It is a different engine: the provisioning logic lives in Entra ID and the on-prem agent is a thin connector. That buys multi-agent HA, no SQL/LocalDB to babysit, and portal-driven config — but it drops features. Confirm none of these are load-bearing before you start.

Capability Connect Sync Cloud Sync
Multi-forest / disconnected forests Single agent, requires connectivity to all Per-forest agents, no inter-forest trust needed
High availability Active + staging server Multiple active agents, automatic failover
Sync engine location On-prem (SQL/LocalDB) Entra ID cloud service
Device sync / Hybrid Entra Join Supported Not supported
Pass-through Authentication (PTA) Supported Supported
Password hash sync (PHS) Supported Supported
Password writeback / group writeback Supported Supported (writeback enabled separately)
Exchange hybrid writeback Supported Not supported
Large object volume 100k+ tested heavily Scales, but validate against your object count
Filtering on attribute values / custom expressions Full Sync Rules Editor Attribute mapping + scoping filters (more limited)

Use the official Connect to Cloud Sync decision guide to confirm coverage. If you rely on Hybrid Entra Join via sync, Exchange hybrid attribute writeback, or heavy custom sync-rule transformations, you are not a clean migration candidate yet — stay on Connect Sync or run a permanent hybrid of both engines.

Supported coexistence topologies

The migration leans on a supported topology: Connect Sync and Cloud Sync running against the same forest with mutually exclusive scopes. The golden rule: any object must be in scope of exactly one engine at a time. Overlap means two agents writing the same target object — export errors and attribute thrash.

2. Prerequisites and a configuration backup

Lock these down first. Skipping the source-anchor check is the classic way to turn a migration into a duplicate-object incident.

Back up the Connect Sync config so you can roll back the rule changes cleanly:

# Run on the active Connect Sync server (elevated)
# Exports server config, including all custom sync rules, to a timestamped folder
$stamp = Get-Date -Format 'yyyyMMdd-HHmmss'
Import-Module 'C:\Program Files\Microsoft Azure AD Connect\AdSync\AdSync.psd1'
$out = "C:\ConnectSync-Backups\$stamp"
New-Item -ItemType Directory -Path $out -Force | Out-Null

# Built-in export wizard switch produces an Exported-ServerConfiguration-*.json bundle
Start-Process 'C:\Program Files\Microsoft Azure AD Connect\AzureADConnect.exe' `
  -ArgumentList "/exportConfig `"$out`""

Also record your current connector source anchor in the Connect Sync wizard (Synchronization Service Manager -> Connectors). If it is anything other than objectGUID / mS-DS-ConsistencyGuid, stop and fix that before continuing — Cloud Sync cannot reliably hard-match otherwise.

3. Install and register provisioning agents for HA

Cloud Sync supports multiple active agents. For production, install at least two on separate hosts per forest so that a server reboot does not stall provisioning. The first agent creates the group Managed Service Account (gMSA); subsequent agents reuse it.

  1. In the Entra admin center: Entra Connect -> Cloud Sync -> Agents -> Download on-premises agent.
  2. Run AADConnectProvisioningAgentSetup.exe on each host.
  3. In the wizard, sign in as Hybrid Identity Administrator, then Configure Service Account:
    • First agent: choose Create gMSA (creates provAgentgMSA$) — needs Domain Admin once to create the account.
    • Additional agents: also choose Create gMSA; the wizard detects the existing provAgentgMSA$ and grants the new host permission to use it.
  4. Add your AD domain under Connect Active Directory, authenticate, Confirm to register and start the agent.

Verify the agent locally on each host:

# Both services must be present and Running
Get-Service 'Microsoft Azure AD Connect Provisioning Agent',
            'Microsoft Azure AD Connect Agent Updater' |
  Format-Table Name, Status, StartType

Then confirm registration in Entra Connect -> Cloud Sync -> Agents — each agent should show status active. Two active agents against the same domain is the HA posture you want.

4. Build the coexistence sync rules in Connect Sync

This is the heart of safe coexistence. Before Cloud Sync touches an object, you teach Connect Sync to stop exporting the objects you are about to migrate — without removing them from scope (which would delete them). The mechanism is the cloudNoFlow attribute and the JoinNoFlow link type.

The flow: an inbound rule stamps cloudNoFlow=True on in-scope metaverse objects; an outbound rule with link type JoinNoFlow sees that flag and suppresses the export to Entra ID. The connector link stays intact (no delete), but attribute flow stops, leaving Cloud Sync free to own those attributes.

First, freeze the scheduler so no sync runs while you edit rules:

# On the Connect Sync server (elevated)
Stop-ADSyncSyncCycle
Set-ADSyncScheduler -SyncCycleEnabled $false
# If you run a custom scheduler, disable that instead.

Inbound rule (stamp the flag)

Open the Synchronization Rules Editor, set Direction to Inbound, Add new rule:

Field Value
Connected System Your on-prem AD connector
Connected System Object Type user
Metaverse Object Type person
Link Type Join
Precedence A unique unused number (e.g. 50)

Outbound rule (suppress the export)

Set Direction to Outbound, Add rule:

Field Value
Connected System Your Entra ID connector
Connected System Object Type user
Metaverse Object Type person
Link Type JoinNoFlow
Precedence A unique unused number

Repeat both rules for every object type you are migrating — user, group, and contact — and for each AD connector if you have multiple forests. A missing group outbound rule is exactly how groups get hard-deleted on cutover.

5. Configure the Cloud Sync side with matching scope

In Entra Connect -> Cloud Sync -> New configuration:

  1. Select the AD domain and decide on password hash sync (enable it here if PHS is your auth method — see Section 7).
  2. Create, then open Scoping filters.
  3. Choose Selected organizational units and enter the same OU you scoped in the Connect Sync inbound rule: OU=CloudSyncPilot,DC=contoso,DC=com. Mutually exclusive scope alignment is what prevents double-provisioning.
  4. Review Attribute mappings. Cloud Sync ships sensible defaults; add directory extension attributes or expression mappings here if your tenant depends on them. Keep the matching/anchor attribute aligned with your Connect Sync source anchor.
  5. Leave the configuration disabled (do not enable provisioning yet) so you can validate with on-demand provisioning first.

Restart the Connect Sync scheduler so the cloudNoFlow rules take effect:

Set-ADSyncScheduler -SyncCycleEnabled $true
Start-ADSyncSyncCycle

After the next cycle, Connect Sync stops exporting changes for objects where cloudNoFlow=truewith one caveat: if a reference attribute such as manager changes, Connect Sync ignores cloudNoFlow and exports the full object. Plan your cutover window to avoid bulk org-chart/manager changes mid-migration.

6. Pilot: on-demand provisioning before you enable

Never enable a fresh configuration blind. Use Provision on demand to push a single known user through end to end:

Once on-demand shows a clean hard match with the expected attribute updates, enable the configuration. Cloud Sync now owns the pilot OU; Connect Sync holds the link but flows nothing.

Verify

Confirm the handoff worked before widening scope.

# 1) Connect Sync is no longer exporting the migrated objects.
#    Spot-check a pilot user: cloudNoFlow should be True in the metaverse.
Import-Module 'C:\Program Files\Microsoft Azure AD Connect\AdSync\AdSync.psd1'
$mv = Get-ADSyncCSObject -DistinguishedName 'CN=Pilot User,OU=CloudSyncPilot,DC=contoso,DC=com' `
  -ConnectorName '<your AD connector name>'
$mv | Select-Object DistinguishedName, ConnectorName
# Then trace its metaverse object in the Sync Service Manager and confirm cloudNoFlow = True.

Then verify in Entra:

7. Password hash sync, groups, and deletion protection

Password hash sync. PHS is a per-engine setting; enable it on the Cloud Sync configuration (Section 5). For a clean handoff you want only one engine performing PHS for a given object — once Cloud Sync owns the pilot, it owns hash sync for those users. Validate sign-in for a pilot account immediately after enabling.

Group provisioning. The highest-risk surface. Groups are hard-deleted if they fall out of scope unprotected, and Connect Sync does not populate ms-DS-ConsistencyGuid for groups by default. Confirm the group cloudNoFlow rules exist (Section 4), confirm ms-DS-ConsistencyGuid is populated on in-scope groups, and validate group membership in the provisioning logs before trusting the handoff.

Accidental-deletion protection. Cloud Sync enforces a deletion threshold — if a cycle would delete more objects than the configured limit, it halts and quarantines instead of cascading deletes. Set it deliberately for your scope size:

# Requires the Microsoft.Graph PowerShell module and a Hybrid Identity Admin sign-in.
# Reads, then sets, the Cloud Sync accidental-deletion threshold (objects per cycle).
Connect-MgGraph -Scopes 'Synchronization.ReadWrite.All'

# Inspect current setting
Get-MgServicePrincipalSynchronizationJobSchema `
  -ServicePrincipalId '<provisioning-SP-id>' -SynchronizationJobId '<job-id>'

# Tune the threshold under Cloud Sync -> configuration -> Accidental deletions in the portal,
# or via the synchronization job settings. Keep it just above expected churn, not wide open.

If a cycle trips the threshold, Cloud Sync pauses the job and surfaces it in the portal for you to review and either allow or reject. Treat a tripped threshold as a signal that scope changed unexpectedly — investigate before clicking “allow deletions.”

8. Cutover: widen scope and decommission Connect Sync

With the pilot validated, expand in controlled waves rather than one big bang:

  1. Widen scope in lockstep. For each new wave, add the OU/group to both the Connect Sync cloudNoFlow rules (inbound + outbound, all object types) and the Cloud Sync scoping filter. Always keep the two engines’ scopes mutually exclusive.
  2. Validate each wave with provisioning logs (Update/Success, no Create) before starting the next. Resist the urge to dump the whole directory in at once.
  3. Migrate auxiliary features last: password/group writeback and PTA, if used, should be reconfigured on Cloud Sync and validated per wave.
  4. Final wave brings the remainder of the directory under Cloud Sync.

Once every object is owned by Cloud Sync and provisioning logs are clean for a full business cycle (at least a week, to catch joiners/movers/leavers), retire Connect Sync:

# On the Connect Sync server, after ALL objects are confirmed owned by Cloud Sync.
# Stop and disable the scheduler so it can never export again.
Stop-ADSyncSyncCycle
Set-ADSyncScheduler -SyncCycleEnabled $false

Do not uninstall Connect Sync immediately. Leave the server in place (powered on, sync disabled) as a rollback path for a defined soak period — two to four weeks is typical. Only after the soak, with zero Cloud Sync issues, uninstall via Programs and Features and decommission the host (and its staging server, if any). Disabling the scheduler before uninstalling guarantees the dying server never exports a stray delete on its way out.

Enterprise scenario

A retail group with two acquired forests (a corp.contoso.com parent and a freshly bought eu.fabrikam.local with no trust) ran a single Connect Sync server straining LocalDB during HR-driven bulk moves. We migrated to Cloud Sync forest-by-forest. The pilot OU handed over cleanly, then the first production wave tripped Cloud Sync’s accidental-deletion quarantine: ~400 objects flagged for delete. The cause was not scope overlap — it was that Connect Sync had never populated ms-DS-ConsistencyGuid on groups, so Cloud Sync soft-matched on mailNickname, missed the renamed distribution groups from a prior Exchange migration, and proposed deleting the unmatched cloud copies.

The fix was to stop trusting the default anchor for groups and stamp ms-DS-ConsistencyGuid from objectGUID before re-running, so Cloud Sync hard-matched instead of guessing:

# Backfill ConsistencyGuid on in-scope groups so Cloud Sync hard-matches.
Get-ADGroup -SearchBase 'OU=Wave1,DC=corp,DC=contoso,DC=com' -Filter * -Properties objectGUID, 'mS-DS-ConsistencyGuid' |
  Where-Object { -not $_.'mS-DS-ConsistencyGuid' } |
  ForEach-Object {
    Set-ADObject -Identity $_.DistinguishedName -Replace @{ 'mS-DS-ConsistencyGuid' = $_.objectGUID.ToByteArray() }
  }

We left the quarantine rejected, ran a delta sync so Connect Sync re-stamped the guids into the metaverse, then re-ran provision-on-demand on three known groups and confirmed an Update verdict before releasing the wave. The lesson the team standardized: never widen a wave until on-demand shows a hard match for the group object type specifically — users matching cleanly tells you nothing about groups.

Migration checklist

Pitfalls

Next steps

After decommissioning, fold Cloud Sync into operational monitoring: alert on provisioning-log failures and quarantine events, periodically review the accidental-deletion threshold against directory growth, and document the multi-agent topology so the next on-call knows which hosts run the agent. Adding a second forest later is now just another agent plus configuration — no staging server, no SQL, no forklift.

Entra IDCloud SyncHybrid IdentityMigrationProvisioning Agent

Comments

// part 2 of 2 · Entra Hybrid Identity Sync

Keep Reading