- Add trigger phrases to frontmatter (M365 tenant, Office 365 admin, etc.) - Add TOC to SKILL.md with proper section navigation - Delete duplicate HOW_TO_USE.md (70% content overlap) - Create references/ directory with deep-dive content: - powershell-templates.md: Ready-to-use script templates - security-policies.md: Conditional Access, MFA, DLP guide - troubleshooting.md: Common issues and solutions - Move Python tools to scripts/ directory (standard pattern) - Consolidate best practices into actionable workflows - Fix second-person voice throughout Addresses Progressive Disclosure Architecture feedback. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
9.6 KiB
Troubleshooting Guide
Common issues and solutions for Microsoft 365 tenant administration.
Table of Contents
- Authentication Errors
- PowerShell Module Issues
- Permission Problems
- License Assignment Failures
- DNS and Domain Issues
- Conditional Access Lockouts
- Mailbox Issues
Authentication Errors
"AADSTS50076: MFA Required"
Cause: User requires MFA but hasn't completed it.
Solutions:
- Complete MFA registration at https://aka.ms/mfasetup
- Use interactive authentication:
Connect-MgGraph -Scopes "User.Read.All" -UseDeviceAuthentication - Check Conditional Access policies excluding the user
"AADSTS65001: User hasn't consented"
Cause: Application requires permissions user hasn't granted.
Solutions:
- Grant admin consent in Azure AD portal
- Use admin account for initial consent:
Connect-MgGraph -Scopes "User.ReadWrite.All" -ContextScope Process - Add application to enterprise applications with pre-consent
"AADSTS700016: Application not found"
Cause: App registration missing or incorrect tenant.
Solutions:
- Verify app ID in Azure AD > App registrations
- Check multi-tenant setting if cross-tenant
- Re-register application if needed
"Access Denied" Despite Admin Role
Causes:
- PIM role not activated
- Role assignment pending
- Conditional Access blocking
Solutions:
- Activate PIM role:
- Go to Azure AD > Privileged Identity Management
- Activate required role
- Wait 5-10 minutes for role propagation
- Check Conditional Access policies in report-only mode
PowerShell Module Issues
Module Not Found
Error: The term 'Connect-MgGraph' is not recognized
Solutions:
# Install module
Install-Module Microsoft.Graph -Scope CurrentUser -Force
# If already installed, import explicitly
Import-Module Microsoft.Graph
# Check installation
Get-InstalledModule Microsoft.Graph
Module Version Conflicts
Error: Assembly with same name already loaded
Solutions:
# Remove all versions
Get-Module Microsoft.Graph* | Remove-Module -Force
# Clear cache
Remove-Item "$env:USERPROFILE\.local\share\powershell\*" -Recurse -Force
# Reinstall
Install-Module Microsoft.Graph -Force -AllowClobber
Exchange Online Connection Failures
Error: Connecting to remote server failed
Solutions:
# Use modern authentication
Connect-ExchangeOnline -UserPrincipalName admin@tenant.com
# If MFA issues, use device code
Connect-ExchangeOnline -Device
# Check WinRM service
Get-Service WinRM | Start-Service
Graph API Throttling
Error: 429 Too Many Requests
Solutions:
- Implement retry logic:
$retryCount = 0 $maxRetries = 3 do { try { $result = Get-MgUser -All break } catch { if ($_.Exception.Response.StatusCode -eq 429) { $retryAfter = $_.Exception.Response.Headers['Retry-After'] Start-Sleep -Seconds ([int]$retryAfter + 5) $retryCount++ } else { throw } } } while ($retryCount -lt $maxRetries) - Reduce batch sizes
- Use delta queries for incremental updates
Permission Problems
Insufficient Privileges for User Creation
Error: Insufficient privileges to complete the operation
Required Permissions:
- User Administrator role
- OR User.ReadWrite.All Graph permission
Solutions:
- Verify role assignment:
Get-MgDirectoryRoleMember -DirectoryRoleId (Get-MgDirectoryRole -Filter "displayName eq 'User Administrator'").Id - Request role assignment or PIM activation
- Use service principal with appropriate permissions
Cannot Modify Another Admin
Error: Cannot update privileged user
Cause: Attempting to modify user with equal or higher privileges.
Solutions:
- Use account with higher privilege level
- Global Admin required to modify other Global Admins
- Remove target's admin role first (if appropriate)
Application Permission vs Delegated
Issue: Script works interactively but fails in automation
Solution: Use application permissions for automation:
# Application authentication (daemon/service)
$clientId = "app-id"
$tenantId = "tenant-id"
$clientSecret = ConvertTo-SecureString "secret" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($clientId, $clientSecret)
Connect-MgGraph -ClientSecretCredential $credential -TenantId $tenantId
License Assignment Failures
"Usage location must be specified"
Error: License assignment failed because UsageLocation is not set
Solution:
# Set usage location before license assignment
Update-MgUser -UserId user@tenant.com -UsageLocation "US"
# Then assign license
$license = @{
AddLicenses = @(@{SkuId = "sku-id"})
RemoveLicenses = @()
}
Set-MgUserLicense -UserId user@tenant.com -BodyParameter $license
"No available licenses"
Error: License quota exceeded
Solutions:
- Check available licenses:
Get-MgSubscribedSku | Select-Object SkuPartNumber, @{N='Available';E={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}} - Remove licenses from inactive users
- Purchase additional licenses
Conflicting Service Plans
Error: Conflicting service plans
Cause: User has license with overlapping services.
Solution:
# Check current licenses
Get-MgUserLicenseDetail -UserId user@tenant.com |
Select-Object SkuPartNumber, @{N='Plans';E={$_.ServicePlans.ServicePlanName}}
# Remove conflicting license first
$remove = @{
AddLicenses = @()
RemoveLicenses = @("conflicting-sku-id")
}
Set-MgUserLicense -UserId user@tenant.com -BodyParameter $remove
# Then add new license
DNS and Domain Issues
Domain Verification Failing
Error: Domain verification record not found
Solutions:
- Verify TXT record:
nslookup -type=TXT domain.com - Check for typos in record value
- Wait 24-48 hours for propagation
- Try alternate verification (MX record)
MX Record Not Resolving
Error: Mail flow disrupted
Diagnostic:
nslookup -type=MX domain.com
# Should return: domain.com.mail.protection.outlook.com
Solutions:
- Verify MX record points to
domain.com.mail.protection.outlook.com - Priority should be 0 or lowest number
- Remove conflicting MX records
SPF Record Issues
Error: SPF validation failed
Correct SPF:
v=spf1 include:spf.protection.outlook.com -all
Common Mistakes:
- Multiple SPF records (only one allowed)
- Missing
-allor using~all - Too many DNS lookups (max 10)
Check:
nslookup -type=TXT domain.com | findstr spf
Conditional Access Lockouts
Locked Out by MFA Policy
Symptoms: Cannot sign in, MFA loop
Immediate Actions:
- Use emergency access account
- Sign in from trusted location/device
- Contact admin to temporarily exclude user
Resolution:
# Add user to CA exclusion group
$group = Get-MgGroup -Filter "displayName eq 'CA-Excluded-Users'"
New-MgGroupMember -GroupId $group.Id -DirectoryObjectId (Get-MgUser -UserId user@tenant.com).Id
Policy Conflicts
Symptoms: Unexpected blocks, inconsistent behavior
Diagnostic:
- Check sign-in logs: Azure AD > Sign-in logs
- Filter by user, check "Conditional Access" tab
- Review which policies applied/failed
Resolution:
- Review all policies in report-only mode
- Check for conflicting conditions
- Ensure proper policy ordering
Break-Glass Procedure
When to use: Complete admin lockout
Steps:
- Sign in with emergency access account
- Go to Azure AD > Security > Conditional Access
- Set all policies to "Report-only"
- Diagnose and fix root cause
- Re-enable policies gradually
Mailbox Issues
Mailbox Not Provisioning
Error: Mailbox doesn't exist
Causes:
- License not assigned
- License assignment pending
- User created without Exchange license
Solutions:
- Verify license:
Get-MgUserLicenseDetail -UserId user@tenant.com - Wait 5-10 minutes after license assignment
- Force mailbox provisioning:
# Reassign license Set-MgUserLicense -UserId user@tenant.com -BodyParameter @{ RemoveLicenses = @("sku-id") AddLicenses = @() } Start-Sleep -Seconds 60 Set-MgUserLicense -UserId user@tenant.com -BodyParameter @{ AddLicenses = @(@{SkuId = "sku-id"}) RemoveLicenses = @() }
Mailbox Size Limit
Error: Mailbox quota exceeded
Solutions:
# Check current quota
Get-Mailbox user@tenant.com | Select-Object ProhibitSendQuota, ProhibitSendReceiveQuota
# Increase quota (if license allows)
Set-Mailbox user@tenant.com -ProhibitSendQuota 99GB -ProhibitSendReceiveQuota 100GB
# Or enable archive
Enable-Mailbox user@tenant.com -Archive
Mail Flow Issues
Diagnostic:
# Test mail flow
Test-Mailflow -TargetEmailAddress external@gmail.com
# Check mail flow rules
Get-TransportRule | Where-Object {$_.State -eq 'Enabled'} | Select-Object Name, Priority, Conditions
# Check connectors
Get-InboundConnector
Get-OutboundConnector
Common Fixes:
- Check transport rules for blocks
- Verify connector configuration
- Check ATP/spam policies
- Review quarantine for false positives