Skip to content

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.

Published17 Sept 2026

Updated4 days ago

Read time9 min. 1,768 words.

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:

  1. Stop using interactive user accounts or saved credentials (Get-Credential, plain-text passwords, or stored user tokens) in scheduled scripts.
  2. Register a dedicated application (service principal) in Microsoft Entra ID for each distinct administrative automation workload.
  3. 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.
  4. Assign strictly scoped application permissions (such as User.Read.All or Group.ReadWrite.All) or role-based access control (RBAC) roles rather than directory-wide Global Administrator access.
  5. Grant tenant admin consent for the required API permissions in the Entra admin center.
  6. 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.
  7. 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, or Connect-AzAccount with -Credential parameters.
  • 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.

Unattended script failureScript calls Connect-MgGraph or Connect-AzAccount with user credentials; Entra returns AADSTS50076 or AADSTS50079 requiring MFANightly employee offboarding, license reclamation, or snapshot backups halt without operator notification
Brittle client secretsAdmin uses a client secret stored in plain text inside .ps1 files or environment variables; secret expires silently after 180 daysAutomation breaks unexpectedly, and plaintext secrets expose the tenant to credential harvesting
Over-privileged applicationIT team grants Directory.ReadWrite.All or assigns Global Administrator to the service principal to make it work quicklyAny compromise of the host running the script allows complete tenant takeover
Exchange Online module mismatchScript attempts app-only authentication with Exchange Online without configuring certificate authentication on the service principalExchange automation commands fail with Unauthorized errors because Exchange Online PowerShell requires certificate thumbprints
Certificate expiry blindnessThe public certificate uploaded to Entra ID expires without automated monitoring or renewal alertsBusiness-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.

Failed script sign-insEntra ID > Monitoring > Sign-in logs > User sign-ins (non-interactive)Error code 50076 (MFA required) or 50079 (MFA registration required) for service accounts
Hardcoded credentialsScript files (.ps1, .bat, .py) and Task Scheduler definitionsUsernames containing @domain.co.uk, plain-text passwords, or Import-Clixml credential files
Existing app registrationsEntra admin center > Applications > App registrationsExpired client secrets, unused apps with tenant-wide permissions, or missing owner metadata
Local certificate storeTarget server > certlm.msc > Personal > CertificatesPrivate key missing, expired certificate, or certificate stored under CurrentUser instead of LocalMachine
Conditional Access baselineEntra ID > Protection > Conditional AccessLegacy 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:

Non-interactive sign-in log extractEntra ID sign-in logs filtered by App ID and error codeIdentifies every legacy script, calling IP address, and target resource before deprecation cutoffs
Scheduled task inventoryPowerShell Get-ScheduledTask exported across all management serversMaps every script location, trigger time, running security context, and parameter string
Current permissions auditScript API calls mapped against Microsoft Graph endpointsEstablishes the exact least-privilege permissions needed for the replacement service principal
Script error transcriptsLocal execution transcripts created via Start-TranscriptDistinguishes between authentication handshake failures and script syntax or runtime errors
Certificate asset recordsCertificate thumbprint, issuer, validity period, and private key access ACLsEnsures 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

  1. Sign in to the Microsoft Entra admin center as an Application Administrator or Cloud Application Administrator.
  2. Navigate to Identity > Applications > App registrations and select New registration.
  3. Name the application descriptively (for example, Automated-User-Lifecycle-Script).
  4. Select Accounts in this organizational directory only (Single tenant).
  5. Leave the Redirect URI blank and select Register.
  6. Under Certificates & secrets, select Certificates > Upload certificate and upload the .cer file exported in Step 1.
  7. 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.

  1. In the app registration, select API permissions > Add a permission > Microsoft Graph.
  2. Choose Application permissions (not Delegated permissions, since the script runs without a signed-in user).
  3. Select only the permissions required for the script (for example, User.ReadWrite.All for onboarding scripts, or Reports.Read.All for licensing audits).
  4. 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.ManageAsApp application 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:

  1. Open certlm.msc on the server.
  2. Navigate to Personal > Certificates.
  3. Right-click the automation certificate and select All Tasks > Manage Private Keys.
  4. 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 Forbidden response.

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

Related notes

Need help mapping this to your own tenant, controls, or assessment timeline?