Field note
Entra ID Mandatory MFA Phase 2 Scripts Fix
Automated scripts and scheduled tasks are failing as Entra ID enforces mandatory MFA. Here is how UK IT teams transition to certificate-based service principals.
Microsoft has expanded tenant-wide mandatory multifactor authentication (MFA) enforcement across all cloud tenants. While Phase 1 focused on browser-based administration in the Azure portal, Microsoft Entra admin center, and Microsoft Intune admin center, Phase 2 extends mandatory MFA enforcement to programmatic command-line interfaces and developer tools. This includes Azure PowerShell, the Azure CLI, Microsoft Graph PowerShell SDK, Azure Developer CLI, and Terraform or Bicep deployments that authenticate using user credentials.
For UK SMEs, this change often manifests as sudden, silent operational failures. Scheduled tasks running on on-premises backup servers, nightly user provisioning scripts run by internal IT teams, and cloud automation runbooks that authenticate using a named admin account fail with authentication errors. Interactive MFA cannot be satisfied by an unattended scheduled task running at 02:00. Fixing this requires eliminating legacy user-credential scripts in favour of certificate-based service principal authentication.
Quick answer
To restore broken automation and prepare scripts for mandatory Entra ID MFA enforcement:
- Stop using interactive user accounts or saved credentials (
Get-Credential, plain-text passwords, or stored user tokens) in scheduled scripts. - Register a dedicated application (service principal) in Microsoft Entra ID for each distinct administrative automation workload.
- Generate an enterprise X.509 certificate and upload the public key (
.cer) to the Entra application registration; never use client secrets for high-privilege automated tasks. - Assign strictly scoped application permissions (such as
User.Read.AllorGroup.ReadWrite.All) or role-based access control (RBAC) roles rather than directory-wide Global Administrator access. - Grant tenant admin consent for the required API permissions in the Entra admin center.
- Refactor your PowerShell or Azure CLI scripts to authenticate non-interactively using the application client ID, tenant ID, and certificate thumbprint stored in the Windows Certificate Store or Azure Key Vault.
- Monitor Entra ID service principal sign-in logs to verify successful unattended authentication.
Who this affects
This enforcement directly impacts IT managers, system administrators, and managed service providers (MSPs) responsible for Microsoft 365 and Azure environments across UK SMEs. You are affected if you run:
- Windows Task Scheduler jobs on internal management servers executing daily user sync, licensing, or backup scripts.
- Azure Automation runbooks or GitHub Actions workflows authenticating to Azure resources with user credentials.
- PowerShell scripts using
Connect-MgGraph,Connect-ExchangeOnline, orConnect-AzAccountwith-Credentialparameters. - Third-party reporting and compliance tools configured with a dedicated administrative user account rather than an app registration.
- Migration and tenant management scripts that rely on user accounts excluded from legacy Conditional Access policies.
Under mandatory MFA Phase 2, Microsoft enforces MFA at the identity provider layer for administrative endpoints. Individual policy exclusions in Conditional Access can no longer bypass MFA for user accounts authenticating to administrative services.
What usually goes wrong
When administrative scripts fail under mandatory MFA, the breakdown typically traces back to architectural shortcuts taken when the scripts were initially authored.
| Breakdown | Technical cause | Operational impact |
|---|---|---|
| Unattended script failure | Script calls Connect-MgGraph or Connect-AzAccount with user credentials; Entra returns AADSTS50076 or AADSTS50079 requiring MFA | Nightly employee offboarding, license reclamation, or snapshot backups halt without operator notification |
| Brittle client secrets | Admin uses a client secret stored in plain text inside .ps1 files or environment variables; secret expires silently after 180 days | Automation breaks unexpectedly, and plaintext secrets expose the tenant to credential harvesting |
| Over-privileged application | IT team grants Directory.ReadWrite.All or assigns Global Administrator to the service principal to make it work quickly | Any compromise of the host running the script allows complete tenant takeover |
| Exchange Online module mismatch | Script attempts app-only authentication with Exchange Online without configuring certificate authentication on the service principal | Exchange automation commands fail with Unauthorized errors because Exchange Online PowerShell requires certificate thumbprints |
| Certificate expiry blindness | The public certificate uploaded to Entra ID expires without automated monitoring or renewal alerts | Business-critical automation stops working without clear diagnostic messages in local script logs |
What to check first
Before editing any script code, review your tenant sign-in logs and script inventory to diagnose the exact failure mode.
| Diagnostic check | Location to inspect | Red flag to look for |
|---|---|---|
| Failed script sign-ins | Entra ID > Monitoring > Sign-in logs > User sign-ins (non-interactive) | Error code 50076 (MFA required) or 50079 (MFA registration required) for service accounts |
| Hardcoded credentials | Script files (.ps1, .bat, .py) and Task Scheduler definitions | Usernames containing @domain.co.uk, plain-text passwords, or Import-Clixml credential files |
| Existing app registrations | Entra admin center > Applications > App registrations | Expired client secrets, unused apps with tenant-wide permissions, or missing owner metadata |
| Local certificate store | Target server > certlm.msc > Personal > Certificates | Private key missing, expired certificate, or certificate stored under CurrentUser instead of LocalMachine |
| Conditional Access baseline | Entra ID > Protection > Conditional Access | Legacy named location exclusions created to let scripts bypass MFA from an office public IP |
Evidence to collect
Gather this diagnostic baseline before changing your script authentication architecture:
| Required evidence | Source | Why it matters |
|---|---|---|
| Non-interactive sign-in log extract | Entra ID sign-in logs filtered by App ID and error code | Identifies every legacy script, calling IP address, and target resource before deprecation cutoffs |
| Scheduled task inventory | PowerShell Get-ScheduledTask exported across all management servers | Maps every script location, trigger time, running security context, and parameter string |
| Current permissions audit | Script API calls mapped against Microsoft Graph endpoints | Establishes the exact least-privilege permissions needed for the replacement service principal |
| Script error transcripts | Local execution transcripts created via Start-Transcript | Distinguishes between authentication handshake failures and script syntax or runtime errors |
| Certificate asset records | Certificate thumbprint, issuer, validity period, and private key access ACLs | Ensures backup keys exist and expiry schedules are logged in the team change management register |
Fix path
Follow this structured transition path to replace interactive user authentication with a hardened, certificate-authenticated service principal.
Step 1: Create a dedicated enterprise certificate
Generate a self-signed X.509 certificate for the automation service, or issue one from your internal enterprise Public Key Infrastructure (PKI). Run this command on the server where the script executes:
# Generate self-signed certificate for Microsoft Graph automation
$cert = New-SelfSignedCertificate `
-Subject "CN=M365-Automation-MgGraph" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-KeyExportPolicy Exportable `
-KeySpec Signature `
-KeyLength 2048 `
-KeyAlgorithm RSA `
-HashAlgorithm SHA256 `
-NotAfter (Get-Date).AddYears(2)
# Export public key (.cer) to upload to Entra ID
Export-Certificate -Cert $cert -FilePath "C:\Certs\M365-Automation-MgGraph.cer"
Step 2: Register the application in Microsoft Entra ID
- Sign in to the Microsoft Entra admin center as an Application Administrator or Cloud Application Administrator.
- Navigate to Identity > Applications > App registrations and select New registration.
- Name the application descriptively (for example,
Automated-User-Lifecycle-Script). - Select Accounts in this organizational directory only (Single tenant).
- Leave the Redirect URI blank and select Register.
- Under Certificates & secrets, select Certificates > Upload certificate and upload the
.cerfile exported in Step 1. - Record the Application (client) ID, Directory (tenant) ID, and Thumbprint.
Step 3: Grant least-privilege application permissions
Never grant broad administrative roles when specific API permissions suffice.
- In the app registration, select API permissions > Add a permission > Microsoft Graph.
- Choose Application permissions (not Delegated permissions, since the script runs without a signed-in user).
- Select only the permissions required for the script (for example,
User.ReadWrite.Allfor onboarding scripts, orReports.Read.Allfor licensing audits). - Select Grant admin consent for [Your Tenant] to authorize the permissions.
If the automation requires Exchange Online management:
- Assign the Exchange Administrator directory role to the service principal under Entra ID > Roles and administrators, or assign granular Exchange RBAC roles using
New-ManagementRoleAssignment. - Grant the service principal access within Exchange Online using the
Exchange.ManageAsAppapplication permission.
Step 4: Refactor PowerShell scripts for certificate authentication
Update your script to connect using the certificate thumbprint stored in the Windows Certificate Store:
# Parameters
$TenantId = "11111111-2222-3333-4444-555555555555"
$ClientId = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
$Thumbprint = "0123456789ABCDEF0123456789ABCDEF01234567"
# Connect to Microsoft Graph using Certificate Authentication
try {
Connect-MgGraph `
-ClientId $ClientId `
-TenantId $TenantId `
-CertificateThumbprint $Thumbprint `
-NoWelcome
Write-Output "Successfully authenticated to Microsoft Graph as Service Principal."
}
catch {
Write-Error "Failed to authenticate to Microsoft Graph: $_"
exit 1
}
# Example: Read-only query against Entra users
$inactiveUsers = Get-MgUser -Filter "accountEnabled eq false" -Property Id,DisplayName,UserPrincipalName -All
Write-Output "Retrieved $($inactiveUsers.Count) disabled user accounts."
# Disconnect session at script completion
Disconnect-MgGraph
For scripts targeting Azure resource management via Azure PowerShell:
# Connect to Azure Resource Manager non-interactively
Connect-AzAccount `
-ServicePrincipal `
-ApplicationId $ClientId `
-TenantId $TenantId `
-CertificateThumbprint $Thumbprint
Step 5: Secure the private key and manage permissions
When running scheduled tasks under Windows service accounts (such as NT AUTHORITY\NETWORK SERVICE or a dedicated Managed Service Account), verify that the account has read permissions to the private key:
- Open
certlm.mscon the server. - Navigate to Personal > Certificates.
- Right-click the automation certificate and select All Tasks > Manage Private Keys.
- Grant Read permission to the specific service account executing the scheduled task. Do not grant Full Control.
Common mistakes
- Using client secrets instead of certificates: While client secrets are supported by some PowerShell modules, secrets are passwords stored in plain text. They leak into version control, cannot be protected by the local hardware or operating system certificate store, and expire silently. Certificates provide cryptographically secure, auditable authentication.
- Granting Global Administrator to service principals: Assigning the Global Administrator role to an application registration is the fastest way to turn a routine script into an enterprise security exposure. Use granular Graph application permissions and scoped directory roles.
- Ignoring certificate expiration dates: Unlike interactive users who receive password expiry prompts, service principal certificates fail with zero warning when they expire. Implement an automated calendar alert or Intune/Azure Monitor alert at 60 and 30 days prior to certificate expiry.
- Running scheduled tasks as interactive domain admins: Running scheduled tasks under a personal Domain Admin or Global Admin user account couples infrastructure automation to individual human staff members, breaking when employees leave or change their passwords.
- Forgetting admin consent: Adding application permissions in the Entra portal without selecting the "Grant admin consent" button leaves the permissions in an unauthorized state. Scripts will authenticate successfully but fail on the first API call with a
403 Forbiddenresponse.
Related route
If your organisation needs assistance auditing legacy automation accounts, designing least-privilege application governance, or aligning authentication controls with Cyber Essentials Plus standards, explore our Entra ID Conditional Access consulting service.
References
- Microsoft Learn: Mandatory multifactor authentication for Microsoft Entra ID
- Microsoft Learn: Create an Entra ID application and service principal
- Microsoft Learn: Authentication commands in Microsoft Graph PowerShell SDK
- Microsoft Learn: App-only authentication for unattended scripts in Exchange Online PowerShell
Related notes
17 Sept 2026 · 9 min
Related: windows laps entra id, intune cloud laps setup, local administrator password solution.
11 Jul 2026 · 5 min
Related: microsoft entra connect, entra cloud sync, hybrid identity.
16 Mar 2026 · 4 min
Related: passkeys, entra id, mfa.
Need help mapping this to your own tenant, controls, or assessment timeline?