All users in Finance
(user.department -eq "Finance")
Identity, Access, and Hybrid Sync
A working reference for administering Microsoft Entra ID: how identity flows from on-premises Active Directory into the cloud, how to manage users, groups, and roles the right way, how Conditional Access actually gets enforced, and what to check first when a sign-in fails. Written for the person on call, not the marketing deck.
Entra ID is not just "Active Directory in the cloud." It's a separate identity platform with its own object model, its own trust boundaries, and its own way of deciding whether a device counts as managed. The first thing to get right on any new environment is knowing which join state each device is actually in, because that single fact decides whether Conditional Access, Intune policy, and single sign-on will work at all.
| Join state | What it means | Typical device | SSO to cloud apps |
|---|---|---|---|
| Entra joined | Device trusts Entra ID directly, no on-prem AD account at all | Cloud-first laptops, new hires, Autopilot devices | Native, no extra config |
| Hybrid Entra joined | Device is joined to on-prem AD, then registered to Entra ID via Entra Connect or Cloud Sync | Existing domain-joined desktops in a hybrid environment | Works, but depends on sync health |
| Entra registered | Personal or unmanaged device just added an account for app access, no organizational trust | BYOD phones, personal laptops | Limited, app-level only |
Check any device's actual state with dsregcmd /status. Don't assume, verify. A device that shows AzureAdJoined: NO and DomainJoined: YES is domain-joined only, not hybrid, and will fail modern auth flows that expect a cloud trust.
Nothing in Entra ID is authoritative for a synced object; the on-prem AD attribute always wins. Editing a synced user's properties directly in Entra ID gets silently overwritten on the next sync cycle.
| Tool | What it syncs | Best fit |
|---|---|---|
| Entra Connect Sync | Full object sync, password hash sync or pass-through auth, writeback | Larger environments needing writeback (password writeback, group writeback) |
| Cloud Sync (lightweight agent) | Same core object sync, simpler agent, multiple lightweight agents for redundancy | Multi-forest environments, simpler setup, easier failover |
Groups are how almost everything gets targeted in Entra ID: licenses, Conditional Access, Intune policy, app access. Get the group model right early, because untangling a mess of one-off manual group memberships later is one of the most tedious cleanup jobs in the job.
| Type | Membership | Use for |
|---|---|---|
| Security group, assigned | Manually added members | Small, stable teams; break-glass accounts; admin role assignment |
| Security group, dynamic | Rule-based, evaluated automatically | Department, job title, or device attribute targeting at scale |
| Microsoft 365 group | Assigned or dynamic | Teams, SharePoint, shared mailbox provisioning bundled together |
(user.department -eq "Finance")
(user.jobTitle -contains "Help Desk")
(device.deviceOSType -eq "Windows") and (device.deviceOSVersion -startsWith "10.0.22")
(user.userType -eq "Member") and (user.accountEnabled -eq true) and -not (user.userPrincipalName -match "svc-")
Connect-MgGraph -Scopes "User.ReadWrite.All", "Group.ReadWrite.All", "Directory.Read.All"
New-MgUser -DisplayName "Jordan Diaz" -UserPrincipalName "jdiaz@corp.onmicrosoft.com" `
-MailNickname "jdiaz" -AccountEnabled `
-PasswordProfile @{ Password = "TempPass!2026"; ForceChangePasswordNextSignIn = $true }
Add-MgGroupMember -GroupId $groupId -DirectoryObjectId $userId
Get-MgUser -All | Select-Object DisplayName, UserPrincipalName, AccountEnabled, Department | Export-Csv -Path "C:\Temp\users-audit.csv" -NoTypeInformation
Get-MgUserLicenseDetail -UserId $userId
Group-based licensing (assigning a license SKU to a group instead of individual users) is the recommended approach; it removes the need to touch licenses per person.
Standing admin access is a liability. Privileged Identity Management (PIM) turns permanent role assignments into time-bound, justified, auditable activations, so an account only carries elevated rights for as long as the work actually takes.
| Role | Scope | Typical assignment |
|---|---|---|
| Global Administrator | Full tenant control | Eligible (PIM), never permanent; break-glass accounts excluded from PIM entirely |
| User Administrator | Create/manage users and groups, reset non-admin passwords | Tier 2 identity team, eligible |
| Helpdesk Administrator | Reset passwords for non-admin users, limited scope | Tier 1 support, can be permanent for a small, monitored team |
| Conditional Access Administrator | Manage Conditional Access policies only | Security team, eligible |
| Intune Administrator | Full Intune management | Endpoint team, eligible |
Run PIM access reviews quarterly for Global Administrator and other high-impact roles. Anyone who hasn't activated the role in 90 days is a candidate for removal.
Get-MgRoleManagementDirectoryRoleAssignment -Filter "roleDefinitionId eq '$roleId'"
New-MgRoleManagementDirectoryRoleAssignmentScheduleRequest -Action "selfActivate" `
-PrincipalId $userId -RoleDefinitionId $roleId `
-DirectoryScopeId "/" -Justification "Investigating sign-in failure ticket #4521" `
-ScheduleInfo @{ StartDateTime = (Get-Date); Expiration = @{ Type = "AfterDuration"; Duration = "PT4H" } }
Conditional Access is the enforcement layer that turns "we have a policy" into "the sign-in actually gets blocked or challenged." Every policy is built from the same four building blocks, and almost every troubleshooting question comes down to which one of those four is not doing what you expect.
| Policy | Assignment | Grant control |
|---|---|---|
| Require MFA for all users | All users, all cloud apps | Require multifactor authentication |
| Block legacy authentication | All users, condition: client apps = legacy auth clients | Block access |
| Require compliant device | All users, all cloud apps | Require device to be marked compliant |
| Require MFA for admin roles | Directory role assignment (Global Admin, etc.), all cloud apps | Require multifactor authentication, no exceptions |
| Block by location | All users, condition: named location not in trusted list | Block access |
Never flip a new policy straight to On. Report-only logs what would have happened without actually blocking anyone.
Entra ID sign-in logs have a Conditional Access tab showing exactly which policies would apply and their simulated result per sign-in.
Even after Report-only review, switch On for a small pilot group before applying to All users.
Every Conditional Access policy should exclude at least two emergency access accounts, stored offline, monitored for any sign-in activity.
A misconfigured CA policy with no exclusion has locked entire tenants out before. Test carefully.New-MgIdentityConditionalAccessPolicy -DisplayName "Require MFA - All Users" `
-State "enabledForReportingButNotEnforced" `
-Conditions @{ Applications = @{ IncludeApplications = @("All") }; Users = @{ IncludeUsers = @("All"); ExcludeUsers = @($breakGlassId) } } `
-GrantControls @{ Operator = "OR"; BuiltInControls = @("mfa") }
Not all MFA methods are equal, and the strongest available method should be the default, not the fallback. Set the direction here, then use Authentication Strengths inside Conditional Access to require a stronger method for the sensitive stuff.
| Method | Strength | Best for |
|---|---|---|
| FIDO2 security key | Phishing-resistant | Admin roles, high-value targets |
| Certificate-based authentication | Phishing-resistant | Environments already running smart cards or PKI |
| Microsoft Authenticator, push notification | Strong, but vulnerable to prompt-bombing without number matching | General workforce, enable number matching |
| Temporary Access Pass | Time-limited, single or limited use | Onboarding new hires, passwordless bootstrap, account recovery |
| SMS or voice call | Weakest, vulnerable to SIM swap | Last resort only, plan to retire |
Create a custom Authentication Strength containing only FIDO2 and certificate-based auth, then reference it in the admin Conditional Access policy's grant control instead of the generic "require MFA" control.
Most sign-in problems in a hybrid environment trace back to sync, not to Entra ID itself. Knowing the sync cycle and where to look for failures saves hours of chasing the wrong layer.
A full sync scans every object and is much slower; run it only after a schema change or config fix, not routinely.
| Symptom | Likely cause | Fix |
|---|---|---|
| User exists on-prem but not in Entra ID | Object is outside the configured OU sync scope, or filtered by an attribute-based sync rule | Check Entra Connect's OU filtering in the sync configuration |
| Duplicate attribute value error | Two on-prem objects share the same UPN or proxyAddress | Find and fix the duplicate in on-prem AD, the sync engine will not resolve it for you |
| Object in quarantine | Sync connector hit repeated errors for that object | Review the specific error in Entra Connect Health, fix the source attribute |
| Password changes not reflecting in cloud | Password Hash Sync cycle delay (usually under 2 minutes) or the sync service is stopped | Check the Entra Connect sync scheduler service is running |
Start-ADSyncSyncCycle -PolicyType Delta
Get-ADSyncConnectorRunStatus Get-ADSyncScheduler
Open Synchronization Service Manager on the Entra Connect server, check the Operations tab for the latest run, and drill into any object with an error status.
Fast commands for the moment something in identity is broken and someone is waiting.
Update-MgUser -UserId $userId -AccountEnabled:$true
Revoke-MgUserSignInSession -UserId $userId
Use this after a suspected account compromise, it invalidates refresh tokens tenant-wide for that user.
Get-MgUserAuthenticationMethod -UserId $userId Remove-MgUserAuthenticationMethod -UserId $userId -AuthenticationMethodId $methodId
Get-MgAuditLogSignIn -Filter "userPrincipalName eq '$upn' and status/errorCode ne 0" -Top 20
Get-MgUser -All | Where-Object { -not (Get-MgUserLicenseDetail -UserId $_.Id) } |
Select-Object DisplayName, UserPrincipalName
dsregcmd /status
Get-MgDevice -All | Where-Object { $_.ApproximateLastSignInDateTime -lt (Get-Date).AddDays(-90) } |
Select-Object DisplayName, ApproximateLastSignInDateTime
The Entra ID sign-in logs report a specific AADSTS code for every failure. Learn the common ones and you skip most of the guesswork.
| Code | Meaning | Fix |
|---|---|---|
| AADSTS50126 | Invalid username or password | Confirm the account isn't locked and the password wasn't recently changed elsewhere (hybrid password writeback delay) |
| AADSTS50076 | MFA is required but wasn't satisfied for this sign-in | Have the user complete MFA registration or re-authenticate through the MFA prompt |
| AADSTS53003 | Access blocked by a Conditional Access policy | Check the sign-in log's Conditional Access tab to see exactly which policy fired and why |
| AADSTS50079 | User needs to register for MFA before continuing | Direct the user to the registration portal, or extend a Temporary Access Pass |
| AADSTS700016 | Application not found in this tenant's directory | Verify the app registration exists and the tenant ID in the request matches |
| AADSTS90072 | User's home tenant doesn't match the tenant being signed into (guest/B2B scenario) | Confirm the correct tenant URL is being used, or that guest invitation redemption completed |
| AADSTS50034 | The user account doesn't exist in this directory | Check for typos in UPN, or confirm the sync hasn't failed for that object |
| AADSTS165000 | Generic backend service error, often transient | Retry; if persistent, check Entra ID service health for an active incident |
Rule out a tenant-wide incident before digging into one user's account.
The AADSTS code and the Conditional Access evaluation detail are both on that one log entry; don't guess from the user's description alone.
A stale or quarantined sync object explains a surprising number of "the account should work" tickets.