Disclaimer: Some content in this article may be AI-generated and might not be fully accurate. Please double-check any critical information, or reach out to us if you have questions or find any issues.
Users calling with "I can't sign into Office 365" or "I'm getting blocked from my email" usually means Conditional Access policies are doing their job—but sometimes they're blocking legitimate access. PowerShell gives you the tools to diagnose what's happening and why.
TL;DR
- Connect: Connect-AzureAD and Connect-MgGraph
- Check policies: Get-AzureADMSConditionalAccessPolicy
- User status: Get-MgUser -UserId [email protected]
- Sign-in logs: Get-MgAuditLogSignIn
- Device info: Get-MgDevice for registered devices
- Common fixes: Add to emergency access, exclude from policy
Connect to Required Services
You need both Azure AD and Microsoft Graph connections:
# Azure AD (for Conditional Access policies)
Connect-AzureAD
# Microsoft Graph (for sign-in logs and user info)
Connect-MgGraph -Scopes "AuditLog.Read.All", "Directory.Read.All", "User.Read.All"
Check Conditional Access Policies
List all Conditional Access policies:
Get-AzureADMSConditionalAccessPolicy | Select-Object DisplayName, State, Id
Get detailed information about a specific policy:
Get-AzureADMSConditionalAccessPolicy -PolicyId "policy-guid" | ConvertTo-Json -Depth 5
Check which policies apply to a user:
$user = Get-MgUser -UserId "[email protected]"
$policies = Get-AzureADMSConditionalAccessPolicy
foreach ($policy in $policies) {
if ($policy.Conditions.Users.IncludeUsers -contains $user.Id -or
$policy.Conditions.Users.IncludeGroups -contains (Get-MgUserMemberOf -UserId $user.Id).Id) {
Write-Host "Policy $($policy.DisplayName) applies to $($user.DisplayName)"
}
}
Check Recent Sign-in Attempts
Get the last 10 sign-in attempts for a user:
Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]'" -Top 10 |
Select-Object CreatedDateTime, UserPrincipalName, Status, IpAddress, Location, DeviceDetail, ConditionalAccessStatus
Check for failures in the last 24 hours:
$startDate = (Get-Date).AddDays(-1)
Get-MgAuditLogSignIn -Filter "createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ')) and status/errorCode ne 0" -Top 50 |
Select-Object CreatedDateTime, UserPrincipalName, @{Name="Error";Expression={$_.Status.ErrorCode}}, @{Name="Description";Expression={$_.Status.FailureReason}}
Common Conditional Access Errors
Error: "Your sign-in was blocked by Conditional Access"
Check what policies are blocking:
$signin = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]'" -Top 1
$signin.AppliedConditionalAccessPolicies | Where-Object {$_.Result -eq "failure"}
Error: "Device not compliant" or "Device not registered"
Check device registration status:
Get-MgDevice -Filter "displayName eq 'USER-LAPTOP'" | Select-Object DisplayName, IsCompliant, IsManaged, ApproximateLastSignInDateTime
Find all devices for a user:
$user = Get-MgUser -UserId "[email protected]"
Get-MgUserOwnedDevice -UserId $user.Id | Select-Object DisplayName, OperatingSystem, OperatingSystemVersion
Check User Account Status
Verify user account is not blocked:
Get-MgUser -UserId "[email protected]" | Select-Object DisplayName, UserPrincipalName, AccountEnabled, UserType
Check for password expiration or MFA issues:
Get-MgUser -UserId "[email protected]" | Select-Object DisplayName, PasswordPolicies, StrongAuthenticationRequirements
Temporarily Exclude User from Policy
For emergency access, exclude a user from a specific policy:
$policy = Get-AzureADMSConditionalAccessPolicy -PolicyId "policy-guid"
$policy.Conditions.Users.ExcludeUsers += "user-guid"
Update-AzureADMSConditionalAccessPolicy -PolicyId $policy.Id -Conditions $policy.Conditions
Create an emergency access policy:
$emergencyPolicy = New-Object -TypeName Microsoft.Open.MSGraph.Model.AzureADMSConditionalAccessPolicy
$emergencyPolicy.DisplayName = "Emergency Access - $((Get-Date).ToString('yyyy-MM-dd'))"
$emergencyPolicy.State = "enabled"
$emergencyPolicy.Conditions.Users.IncludeUsers = @("emergency-user-guid")
$emergencyPolicy.Conditions.Applications.IncludeApplications = @("All")
$emergencyPolicy.GrantControls.BuiltInControls = @("block")
$emergencyPolicy.GrantControls.Operator = "OR"
New-AzureADMSConditionalAccessPolicy -Policy $emergencyPolicy
Check Location and IP Restrictions
See what locations are blocked/allowed:
Get-AzureADMSNamedLocationPolicy | Select-Object DisplayName, IpRanges, CountriesAndRegions
Check if a user's IP is in a blocked location:
$userSignIns = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]'" -Top 5
foreach ($signin in $userSignIns) {
Write-Host "IP: $($signin.IpAddress) - Location: $($signin.Location.City), $($signin.Location.CountryOrRegion)"
}
Application-Specific Issues
Check which apps are affected by Conditional Access:
$policies = Get-AzureADMSConditionalAccessPolicy
foreach ($policy in $policies) {
if ($policy.State -eq "enabled") {
Write-Host "Policy: $($policy.DisplayName)"
Write-Host "Apps: $($policy.Conditions.Applications.IncludeApplications)"
Write-Host "---"
}
}
Check for app-specific sign-in issues:
Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]' and appId eq '1fec8e78-bce4-4aaf-ab1b-5451cc387264'" -Top 5
Bulk User Analysis
Find all users affected by failed sign-ins in the last 24 hours:
$startDate = (Get-Date).AddDays(-1)
$failedSignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge $($startDate.ToString('yyyy-MM-ddTHH:mm:ssZ')) and status/errorCode ne 0" -Top 100
$failedUsers = $failedSignIns | Group-Object UserPrincipalName |
Select-Object Name, Count, @{Name="LatestError";Expression={($_.Group | Sort-Object CreatedDateTime -Descending | Select-Object -First 1).Status.FailureReason}}
$failedUsers | Sort-Object Count -Descending | Format-Table
Disable Conditional Access Temporarily
For emergency access, disable all policies (use with extreme caution):
# List all enabled policies
Get-AzureADMSConditionalAccessPolicy | Where-Object {$_.State -eq "enabled"} | Select-Object DisplayName, Id
# Disable a specific policy
Update-AzureADMSConditionalAccessPolicy -PolicyId "policy-guid" -State "disabled"
# Re-enable when done
Update-AzureADMSConditionalAccessPolicy -PolicyId "policy-guid" -State "enabled"
Export Configuration for Documentation
Create a report of all Conditional Access policies:
$policies = Get-AzureADMSConditionalAccessPolicy
$report = @()
foreach ($policy in $policies) {
$report += [PSCustomObject]@{
Name = $policy.DisplayName
State = $policy.State
UsersIncluded = $policy.Conditions.Users.IncludeUsers.Count
GroupsIncluded = $policy.Conditions.Users.IncludeGroups.Count
Applications = $policy.Conditions.Applications.IncludeApplications -join "; "
GrantControls = $policy.GrantControls.BuiltInControls -join "; "
}
}
$report | Export-Csv "C:\Temp\ConditionalAccessPolicies.csv" -NoTypeInformation
Best Practices
- Test policies: Always test with a test account before applying broadly
- Use emergency access accounts: Have break-glass accounts excluded from all policies
- Monitor sign-ins: Regularly review failed sign-in attempts
- Document policies: Keep clear documentation of what each policy does
- Use groups wisely: Put users in groups rather than listing individuals
Quick Reference
# Connect
Connect-AzureAD
Connect-MgGraph -Scopes "AuditLog.Read.All", "Directory.Read.All"
# List policies
Get-AzureADMSConditionalAccessPolicy | Select DisplayName, State
# Check user sign-ins
Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]'" -Top 5
# Find blocking policies
Get-MgAuditLogSignIn -Filter "userPrincipalName eq '[email protected]'" -Top 1 |
Select-Object -ExpandProperty AppliedConditionalAccessPolicies |
Where-Object {$_.Result -eq "failure"}
# Temporarily exclude user
$policy = Get-AzureADMSConditionalAccessPolicy -PolicyId "guid"
$policy.Conditions.Users.ExcludeUsers += "user-guid"
Update-AzureADMSConditionalAccessPolicy -PolicyId $policy.Id -Conditions $policy.Conditions
Conditional Access is powerful but can be frustrating when it blocks legitimate access. The key is having the right PowerShell commands to quickly diagnose what's happening and provide targeted solutions rather than disabling security entirely.
Need Help with Microsoft 365 Access Issues?
Conditional Access policies and sign-in troubleshooting can be complex and time-sensitive. My company NHM Ohio provides rapid response Microsoft 365 support to diagnose and resolve access issues before they impact your business.
Whether you need emergency access restoration, policy configuration, or ongoing monitoring, explore our Microsoft 365 services or contact us for immediate assistance.