The practical baseline: require MFA, block legacy auth, protect admins, set up named locations, and always create break-glass accounts before enabling anything.
Conditional access is the enforcement layer that makes MFA mean something. Per-user MFA without conditional access can be bypassed by legacy authentication clients that simply do not send an MFA challenge. Conditional access intercepts the sign-in before a token is issued and applies the policy: require MFA, require a compliant device, block the sign-in entirely, or any combination. Without it, a user with "MFA enabled" can still be compromised via IMAP or SMTP AUTH.
Break-glass accounts are cloud-only Global Administrator accounts with long random passwords, excluded from all conditional access policies, and with no MFA registered. They exist only to be used in an emergency where conditional access is broken or all other admins are locked out.
# Create the account
New-MgUser -DisplayName "Break Glass 01" `
-UserPrincipalName "breakglass01@contoso.onmicrosoft.com" `
-AccountEnabled:$true `
-PasswordProfile @{Password = "$(New-Guid)-$(New-Guid)"; ForceChangePasswordNextSignIn = $false} `
-PasswordPolicies "DisablePasswordExpiration"
# Assign Global Administrator role
$role = Get-MgDirectoryRole | Where-Object DisplayName -eq "Global Administrator"
New-MgDirectoryRoleMember -DirectoryRoleId $role.Id -BodyParameter @{
"@odata.id" = "https://graph.microsoft.com/v1.0/users/$((Get-MgUser -Filter "UserPrincipalName eq 'breakglass01@contoso.onmicrosoft.com'").Id)"
}
Store the credentials in a password manager accessible to the client (not only to your MSP). Create an alert in Entra ID or Defender for any sign-in by the break-glass account; it should never be used in normal operations, so any sign-in is a signal worth investigating.
These four policies cover the most impactful controls for a typical SMB or mid-market tenant. They are ordered by impact and risk; deploy them in this sequence and test each one before enabling the next.
Legacy authentication protocols (IMAP, POP3, SMTP AUTH, older Office clients using basic auth) cannot respond to MFA challenges. They are the single most common attack vector against M365 tenants and serve no legitimate purpose in a modern managed environment. Block them first.
Via PowerShell (Microsoft Graph)
$params = @{
DisplayName = "Block legacy authentication"
State = "enabled"
Conditions = @{
ClientAppTypes = @("exchangeActiveSync", "other")
Users = @{ IncludeUsers = @("All"); ExcludeUsers = @("breakglass01-object-id") }
Applications = @{ IncludeApplications = @("All") }
}
GrantControls = @{ Operator = "OR"; BuiltInControls = @("block") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
After enabling, monitor the sign-in logs for a week. Legitimate legacy auth usage (a scanner using SMTP AUTH, an old line-of-business app using basic auth) will show up as blocked. Each one needs a remediation plan: migrate to modern auth, use an app password if MFA cannot be changed, or use a service account excluded from the policy as a last resort.
All sign-ins to any cloud app require MFA. Exclude break-glass accounts and any service accounts that use app-only authentication (those should not be signing in interactively anyway).
Deploy in report-only mode first
$params = @{
DisplayName = "Require MFA - All users"
State = "enabledForReportingButNotEnforcing"
Conditions = @{
Users = @{
IncludeUsers = @("All")
ExcludeUsers = @("breakglass01-object-id", "breakglass02-object-id")
}
Applications = @{ IncludeApplications = @("All") }
}
GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
Leave it in enabledForReportingButNotEnforcing (report-only mode) for one to two weeks. The sign-in logs will show what would have been blocked, without blocking anyone. This surfaces users with no MFA registered before they hit a wall. Once MFA registration is complete across the tenant, change State to enabled.
Admin accounts are higher-value targets and should be required to MFA even if you use a separate MFA policy for users. This policy targets any user holding a privileged Entra ID role.
$params = @{
DisplayName = "Require MFA - Administrators"
State = "enabled"
Conditions = @{
Users = @{
IncludeRoles = @(
"62e90394-69f5-4237-9190-012177145e10", # Global Administrator
"f28a1f50-f6e7-4571-818b-6a12f2af6b6c", # SharePoint Administrator
"729827e3-9c14-49f7-bb1b-9608f156bbb8", # Helpdesk Administrator
"b0f54661-2d74-4c50-afa3-1ec803f12efe", # Billing Administrator
"b1be1c3e-b65d-4f19-8427-f6fa0d97feb9" # Teams Administrator
)
ExcludeUsers = @("breakglass01-object-id", "breakglass02-object-id")
}
Applications = @{ IncludeApplications = @("All") }
}
GrantControls = @{ Operator = "OR"; BuiltInControls = @("mfa") }
}
New-MgIdentityConditionalAccessPolicy -BodyParameter $params
This policy requires that the device signing in is either Entra ID joined or marked compliant by Intune. It is a strong control but requires Intune device management to be in place; enabling it without Intune means users on unmanaged devices (phones, home computers) cannot sign in at all.
Named locations let you define trusted IP ranges (your client's office IPs, your MSP's egress IPs) and use them in policy conditions. A common use is exempting specific locations from MFA for low-sensitivity apps, or creating a "block sign-in from high-risk countries" policy.
$params = @{
"@odata.type" = "#microsoft.graph.ipNamedLocation"
DisplayName = "Contoso Head Office"
IsTrusted = $true
IpRanges = @(
@{ "@odata.type" = "#microsoft.graph.iPv4CidrRange"; CidrAddress = "203.0.113.0/24" }
)
}
New-MgIdentityConditionalAccessNamedLocation -BodyParameter $params
Use the What If tool in the Entra ID portal (Conditional Access > Policies > What If) to simulate a sign-in for a specific user, app, and location and see which policies would apply and what outcome they would produce. This is the safest way to test before enabling a policy in production.
From PowerShell, review all current policies and their states:
Get-MgIdentityConditionalAccessPolicy | Select-Object DisplayName, State, CreatedDateTime | Sort-Object CreatedDateTime
After enabling any policy, review the sign-in logs for failures caused by it:
Get-MgAuditLogSignIn -Filter "conditionalAccessStatus eq 'failure'" -Top 50 |
Select-Object CreatedDateTime, UserPrincipalName, AppDisplayName, IpAddress,
@{N="CA Policy";E={$_.AppliedConditionalAccessPolicies.DisplayName}} |
Sort-Object CreatedDateTime -Descending
As an MSP admin accessing customer tenants via GDAP, your sign-ins originate from your home tenant but authenticate in the customer tenant. Conditional access policies in the customer tenant apply to your delegated sessions. If you deploy a "require compliant device" policy in a customer tenant, confirm your own devices meet the compliance requirements before enabling it, or exclude your MSP admin accounts from the policy.
For the connection setup side: app-only (certificate-based) connections used in automation are not interactive sign-ins and are not subject to conditional access policies targeting user sign-ins. They are governed by app consent and application permissions instead.