Hybrid identity lives or dies on the sync engine that projects on-premises Active Directory into Microsoft Entra ID. Get the authentication method, the sourceAnchor, and the sync rule precedence right and it runs for years untouched; get them wrong and you are doing a tenant-wide re-sync at 2 a.m.
Naming note: the product formerly known as Azure AD Connect is now Microsoft Entra Connect Sync. The installed component, run profiles, and the
ADSyncPowerShell module are unchanged; only the branding moved.
1. Architecture and choosing your authentication method
Entra Connect Sync synchronizes objects (users, groups, contacts, devices) from one or more AD forests into a single Entra tenant. Authentication — how a user’s password is actually validated — is a separate decision layered on top of sync. You have three options:
| Method | Where password is validated | On-prem dependency at sign-in | Best for |
|---|---|---|---|
| Password Hash Sync (PHS) | In the cloud, against a synced hash-of-a-hash | None — survives an on-prem outage | The default for almost everyone |
| Pass-through Authentication (PTA) | On-prem DC, via lightweight agents | Requires a live agent + DC | “Passwords never leave the building” mandates |
| Federation (AD FS) | On-prem AD FS farm | Requires the whole AD FS estate | Smart-card/3rd-party MFA, legacy claims rules |
Principal’s take: default to PHS. Even if you run PTA or federation, enable PHS as a backstop so that leaked-credential detection (Entra ID Protection) works and you have an instant failover if your agents or AD FS go down. Microsoft’s own guidance is that PHS should be on unless a hard compliance rule forbids it.
PHS does not sync the cleartext or even the NTLM hash to the cloud — it syncs a salted PBKDF2/SHA-256 hash of the NTLM hash, which is not reversible to anything usable against on-prem. PTA keeps validation on-prem but introduces a runtime dependency you must make redundant (see Step 6).
Seamless SSO is orthogonal to all three: it silently signs in domain-joined, corporate-network users with Kerberos so they skip the username/password prompt. It pairs with PHS or PTA (not needed with federation, which handles SSO itself).
2. Pre-flight: UPN, sourceAnchor, and connectivity
Most failed deployments fail here, before installation.
Verify UPN suffixes are routable
Every user’s on-prem userPrincipalName suffix must be a verified custom domain in Entra. The classic trap is users with a non-routable .local UPN suffix. Add a routable suffix in AD and re-stamp users before you sync.
# On a DC: add a routable UPN suffix to the forest
Get-ADForest | Format-List UPNSuffixes
Set-ADForest -Identity contoso.local -UPNSuffixes @{Add="contoso.com"}
# Re-stamp users from .local to the routable suffix
Get-ADUser -Filter "UserPrincipalName -like '*@contoso.local'" -SearchBase "OU=Staff,DC=contoso,DC=local" |
ForEach-Object {
$new = ($_.UserPrincipalName -replace '@contoso\.local$','@contoso.com')
Set-ADUser $_ -UserPrincipalName $new
}
Choose your sourceAnchor wisely
The sourceAnchor is the immutable key linking an on-prem object to its cloud object. Historically people used objectGUID, but that is not preserved if you ever migrate a user to a new forest. Modern installs default to ms-DS-ConsistencyGuid: the wizard writes objectGUID into ms-DS-ConsistencyGuid on first sync, then uses that attribute thereafter. This makes cross-forest migration and disaster recovery dramatically easier.
Decide sourceAnchor once. Changing it after objects exist in the cloud requires deleting and re-matching every synced object. Confirm what is in use:
# On the Connect server
Get-ADSyncGlobalSettings |
Select-Object -ExpandProperty Parameters |
Where-Object { $_.Name -like '*SourceAnchor*' }
# Expect: Microsoft.SynchronizationOption.SourceAnchorAttribute = mS-DS-ConsistencyGuid
Connectivity and prerequisites
- The Connect server needs outbound HTTPS (443) to Entra/Azure endpoints; do not put it behind an authenticating proxy that breaks WS-Trust/modern auth. Most shops put it on a dedicated, hardened, domain-joined Windows Server with no inbound internet exposure.
- Run IdFix against the directory first to clean duplicate/invalid
proxyAddresses,mail, and UPN values. DuplicateproxyAddressesis the number-one export error you can avoid entirely up front. - Use TLS 1.2 and a supported .NET/OS build. Use a group Managed Service Account (gMSA) for the sync service so credential rotation is automatic.
3. Custom installation walkthrough
Use Customize (not Express) for any real environment so you control connectors, filtering, and optional features.
Entra Connect → Customize → Install required components
[x] Use an existing service account -> gMSA: contoso\svc-aadsync$
[x] Specify custom sync groups (ADSyncAdmins, Operators, Browse, PasswordSet)
User sign-in:
(o) Password Hash Synchronization
[x] Enable single sign-on (Seamless SSO)
Connect your directories:
+ Add AD forest -> account with Replicating Directory Changes (for PHS)
Domain/OU filtering:
(o) Sync selected organizational units
[x] OU=Staff [x] OU=ServiceAccounts [ ] OU=Disabled [ ] OU=Computers-Lab
Optional features:
[x] Password hash synchronization
[x] Password writeback (requires Entra ID P1)
[ ] Group writeback
[x] ms-DS-ConsistencyGuid as the source anchor
OU filtering (above) is the coarse, recommended filter — only sync the OUs that hold real identities. For finer control you can add attribute-based filtering via an inbound sync rule that sets cloudFiltered = True for objects matching a condition (for example, a custom extensionAttribute15 flag). Filter out what you do not need; a smaller metaverse is faster and safer.
Do not check Start the synchronization process on the final page of a fresh production install if you have any doubt about filtering. Install in a state where you can inspect the connector space first, then enable the scheduler.
4. How the sync engine actually works
Internally the engine moves data through three logical stores. Understanding them is the difference between guessing and diagnosing.
AD (source) CONNECTOR SPACE METAVERSE CONNECTOR SPACE Entra (target)
objects ---> (AD connector, ---> (single, ---> (Entra connector, ---> objects
staging) authoritative) staging)
[ import ] [ inbound ] [ outbound ] [ export ]
[ profiles ] [ sync rules] [ sync rules] [ profiles]
- Connector space (CS): a per-connector staging copy of source/target objects. There is one CS for each AD forest and one for Entra.
- Metaverse (MV): the single, consolidated view. Inbound sync rules flow attributes CS -> MV; outbound rules flow MV -> CS toward Entra.
- Run profiles do the work, in this order during a delta cycle:
- Delta Import (AD) — pull changes into the AD CS.
- Delta Sync — apply sync rules, recompute the MV, stage changes into the Entra CS.
- Export (Entra) — push staged changes to the tenant.
- Delta Import (Entra) — confirm what the tenant accepted (confirming import).
A Full Import / Full Sync re-reads everything and re-evaluates all rules — you run it only after changing sync rules or filtering, because it is expensive. The default scheduler runs a delta cycle every 30 minutes.
# Inspect and control the scheduler
Get-ADSyncScheduler # NextSyncCyclePolicyType, interval, enabled?
Start-ADSyncSyncCycle -PolicyType Delta # force a delta cycle now
Start-ADSyncSyncCycle -PolicyType Initial # full import + full sync + export (after rule changes)
Set-ADSyncScheduler -SyncCycleEnabled $false # pause (e.g., during maintenance)
5. Writing custom sync rules without breaking precedence
Sync rules are evaluated by precedence — lower number wins. The product ships dozens of default rules occupying precedence values from 0 upward (commonly into the 100s). The cardinal rule:
Never edit a default (Microsoft-authored) rule, and never put a custom rule at a precedence that the product reserves. Author your custom rules at precedence >= 100 below the standard defaults — practically, leave a gap (e.g., start custom rules in the 50–99 band) only if you have audited what is already there. On upgrade, Microsoft can recreate default rules, silently discarding edits you made to them.
The supported pattern to change a default behavior is disable-and-clone:
- Open Synchronization Rules Editor.
- Find the default inbound rule (e.g.,
In from AD - User Join), click Disable (do not delete — the engine recreates deleted defaults). - Clone it, give it a higher precedence number than the original, and edit the clone.
A common real-world need: stop overwriting the cloud mail attribute for a subset of users. Done as a scoped inbound transformation rule:
Synchronization Rules Editor -> Inbound -> Add new rule
Name: In from AD - Custom mail flow
Connected System: contoso.local
CS Object Type: user MV Object Type: person
Link Type: Join
Precedence: 90 (above the default user rules you cloned/disabled)
Scoping filter (group):
department EQUAL "Contractors"
Transformations:
FlowType Target Source / Expression
Constant cloudFiltered False
Direct mail mail
Expression accountEnabled IIF([userAccountControl] BAND 2 = 0, True, False)
On those expressions: cloudFiltered drives whether an object is exported (set True to filter it out), and the accountEnabled expression is how the default rules read the disabled bit (0x2, ACCOUNTDISABLE) out of userAccountControl so disabled AD accounts arrive disabled in Entra. Always export your rule set before and after changes so you can diff and roll back:
# Document the current rule set as code (review in source control)
Get-ADSyncRule | Sort-Object Precedence |
Select-Object Precedence, Name, Direction, Disabled |
Format-Table -AutoSize
# Full, restorable export of every rule
Get-ADSyncRule | ConvertTo-Json -Depth 10 |
Out-File C:\ADSync\sync-rules-backup.json
6. Seamless SSO and PTA agents with redundancy
Pass-through Authentication runs through lightweight PTA Authentication Agents. The Connect server installs the first agent; you must install at least two more on separate servers so a single host outage does not block all sign-ins. Three agents total (the one on the Connect server plus two standalone) is the practical minimum for production.
Download "Microsoft Entra Connect Authentication Agent" -> install on 2+ extra
domain-joined servers (NOT the Connect server). Each registers itself to the tenant.
Verify in portal:
Entra admin center -> Identity -> Hybrid management -> Microsoft Entra Connect
-> Connect Sync / Pass-through authentication -> agents = Active (>= 3)
Seamless SSO works by creating a computer account named AZUREADSSOACC in AD and sharing its Kerberos decryption key with Entra. The critical, frequently-missed operational task is rolling the AZUREADSSOACC Kerberos key at least every 30 days — Microsoft explicitly recommends this. Treat it as a scheduled job.
# On the Connect server, from the Seamless SSO module folder
Import-Module 'C:\Program Files\Microsoft Azure Active Directory Connect\AzureADSSO.psd1'
New-AzureADSSOAuthenticationContext # prompts for a Hybrid Identity Admin
Get-AzureADSSOStatus | ConvertFrom-Json # which domains have Seamless SSO enabled
# Roll the Kerberos decryption key (do this >= every 30 days)
$creds = Get-Credential # on-prem Domain Admin for AZUREADSSOACC
Update-AzureADSSOForest -OnPremCredentials $creds
Client side, Seamless SSO requires the Entra URLs (https://autologon.microsoftazuread-sso.com and https://aadg.windows.net.nsatc.net) to be in the browser’s Intranet zone, typically pushed via Group Policy. Without that, Kerberos silent sign-in falls back to a prompt.
7. High availability: staging mode and upgrades
Entra Connect is active/passive, not active/active. You run a second server in staging mode: it imports and runs sync rules (so its metaverse is warm and current) but does not export to Entra and does not do password writeback. This is your DR box, your safe place to test rule changes, and the target for swing upgrades.
# Confirm a server's role
(Get-ADSyncScheduler).StagingModeEnabled # True on the standby box
# Failover: promote staging to active, then demote the old primary
# Old primary: Set-ADSyncScheduler -StagingModeEnabled $true
# New primary: Set-ADSyncScheduler -StagingModeEnabled $false
Run a failover drill quarterly. Because both servers must use the same sourceAnchor and the same connector/filtering configuration, the safest way to keep them identical is to export the active config and import it on staging:
# On the active server: snapshot full configuration
Get-ADSyncServerConfiguration -Path C:\ADSyncExport
# (then import that snapshot when building/refreshing the staging server)
Upgrade strategy: prefer automatic upgrade for in-place minor updates (Get-ADSyncAutoUpgrade shows the state). For major version jumps, do a swing migration: stand up the new version on the staging server, validate its metaverse and a pending-export preview against production, then flip staging to active. This gives you an instant rollback — just flip back. Entra Connect builds expire (older builds get deprecated and eventually blocked), so do not let the version drift; treat staying current as part of the operational baseline.
Enterprise scenario
A retail platform team ran PTA with three agents and Seamless SSO across two AD forests. Sign-ins started failing intermittently for one business unit after an acquisition forest was onboarded — but only for users whose accounts had been migrated between OUs. Root cause: a previous admin had edited the default In from AD - User Join rule in place to flow a custom employeeId into extensionAttribute2. A minor auto-upgrade silently recreated that default rule, dropping the edit, so cloudFiltered logic downstream stopped scoping correctly and the migrated objects got cloudFiltered = True on the next full sync — they were deleted from the tenant, breaking their PTA sign-in entirely.
The fix was the supported disable-and-clone pattern plus codifying rules in source control so an upgrade can never resurrect a silent default over a hand edit:
# Disable the Microsoft default, clone at a higher precedence, own the change
$def = Get-ADSyncRule | ? { $_.Name -eq 'In from AD - User Join' }
Disable-ADSyncRule -Identifier $def.Identifier
# Snapshot rules as code; diff this in CI on every Connect upgrade
Get-ADSyncRule | Sort-Object Precedence |
Select-Object Precedence, Name, Direction, Disabled, Identifier |
Export-Csv C:\ADSync\rules-baseline.csv -NoTypeInformation
They also moved the employeeId transformation into a cloned inbound rule at precedence 90, re-ran Start-ADSyncSyncCycle -PolicyType Initial, and added a pre/post-upgrade Get-ADSyncRule diff to their change runbook. Lesson: any edit to a Microsoft-authored rule is a time bomb that detonates on the next upgrade — clone, never edit in place, and treat the rule set as version-controlled config.
Verify
Confirm the deployment end to end before you call it done.
# 1. Engine healthy, scheduler enabled, last cycle clean
Get-ADSyncScheduler
Get-ADSyncConnectorRunStatus # should be idle, not stuck "Running"
# 2. No export errors and a sane pending-export count
Get-ADSyncConnectorStatistics -ConnectorName "<tenant> - AAD"
# -> watch ExportAdd/Update/Delete; investigate any *Error counts
# 3. PHS is actually flowing
$c = Get-ADSyncConnector | ? { $_.Type -eq 'Extensible2' }
Get-ADSyncAADPasswordSyncConfiguration -SourceConnector $c.Name # Enabled = True
# 4. Seamless SSO / PTA enabled for the right domains / agents Active
Get-AzureADSSOStatus | ConvertFrom-Json
Then validate from the user’s side: a synced user signs in to https://myapps.microsoft.com; on a domain-joined corp machine they should not be prompted (Seamless SSO), and a password changed on-prem should authenticate in the cloud within the sync interval (PHS) or immediately (PTA). In the portal, check Connect Health (or the Connect blade) for agent status and sync errors.
Checklist
Pitfalls and next steps
- Editing default rules. The single most common self-inflicted outage. Disable-and-clone, always — upgrades resurrect defaults and wipe inline edits.
- Soft-match / hard-match surprises. Pre-existing cloud-only objects match synced ones by primary SMTP (soft match) or by stamping
ImmutableId(hard match). Audit duplicates before sync or you will orphan mailboxes. - Treating PTA as zero-dependency. PTA needs live agents and reachable DCs at every sign-in. Without redundant agents you have built a single point of failure into authentication itself.
- Forgetting the Kerberos key roll. Seamless SSO silently keeps working past 30 days, then becomes a security finding — automate the rotation.
- Version drift. Old Connect builds get deprecated and blocked. Keep auto-upgrade on for minors and rehearse swing migrations for majors.
Next, wire Connect Health alerts to your incident channel, enable password writeback so self-service password reset round-trips to AD, and layer Conditional Access on top so that how identities sync and how they are allowed to sign in are governed as one coherent design.