MfaOnDemand is a PowerShell module designed to send custom and arbitrary MFA requests to Entra ID users and other supported MFA providers.
Useful for quickly confirming user identities for Service Desk usage or for any automation purposes.
- Supports both OTP or Push verification modes
- Integration-ready, quick and straightforward inclusion into existing scripts and workflows
- Utilizes Client Credentials in the form of a Certificate or Secret Key
- Includes helper functions to add, list, and delete Client Credentials
- No need for additional App Registration
- Microsoft Entra ID
- WatchGuard AuthPoint
# From local path
Import-Module .\MfaOnDemand.psd1
# From PowerShell Gallery
Install-Module -Name MfaOnDemand
#In order to trigger Entra ID native MFA you'll first need to register a secret within your Tenant:
$secret = Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type PasswordThis secret will then be used for subsequent MfaOnDemand requests:
Invoke-MoDMfa -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Credential ($secret | ConvertTo-SecureString -AsPlainText -Force) -User user@something.onmicrosoft.com -Mode PushFirst, you must have some type of credential registered on Entra ID MFA App. MfaOnDemand provides the helper function Add-MoDCredentials for convenience:
# Register a new Password credential, valid for 1 day, and output as plain text
Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Password
<#
Register a new X509 Certificate credential, valid for 1 year, and output its Thumbprint,
The certificate is stored on CurrentUser Certificates Store
#>
Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Certificate -MyCertificate New
# Alternatively you can also register an existing X509 certificate
[X509Certificate]$cert | Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Certificate
# or
Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Certificate -MyCertificate <X509Certificate.Thumbprint>The actual MFA request is sent by Invoke-MoDMfa. At least on the first iteration, a -Credential parameter is required to authenticate MfaOnDemand against the MFA Provider. Subsequent calls to Invoke-MoDMfa
can omit it as long as original session is valid.
# Send MFA OTP request, -Credential is a Thumbprint string from an X509Certificate stored in the CurrentUser Certificates Store (Cert:\CurrentUser\My)
Invoke-MoDMfa -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Credential <X509Certificate.Thumbprint> -User user@something.onmicrosoft.com -Mode OTP
# Send MFA OTP request reading -Credential input from Pipeline
[X509Certificate]$cert | Invoke-MoDMfa -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -User user@something.onmicrosoft.com -Mode OTP
# Using Pipeline is also possible to register any supported credential type and feed it to Invoke-MoDMfa
Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Certificate -MyCertificate New | Invoke-MoDMfa -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -User user@something.onmicrosoft.com -Mode OTP
# or
Add-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Type Password | ConvertTo-SecureString -AsPlainText -Force | Invoke-MoDMfa -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -User user@something.onmicrosoft.com -Mode OTPRetrieving all registered credentials is straightforward with Get-MoDCredentials:
# Output both Passwords and Certificates
Get-MoDCredentials -Provider EntraId -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxUsing Get-MoDCredentials will also display suggested commands to remove credentials by KeyId:
#----- USE WITH CAUTION -----
#** Command for password removal
Connect-MgGraph -NoWelcome -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Scopes 'Application.ReadWrite.All'; Remove-MgServicePrincipalPassword -ServicePrincipalId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -KeyId <KeyId>
#** Command for certificate removal
Connect-MgGraph -NoWelcome -TenantId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -Scopes 'Application.ReadWrite.All'; $keyCreds=(Get-MgServicePrincipal -ServicePrincipalId 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx').KeyCredentials; Update-MgServicePrincipal -ServicePrincipalId xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -KeyCredentials ($keyCreds|Where-Object { $_.KeyId -ne '<KeyId>' }) -ConfirmAdditional info can be found on my website.
Invoke-MoDMfa -Credential <password>requires an input of type SecureString, mind that the output ofAdd-MoDCredentials -Type Passwordis in plain text- The use of
Passwordcredentials is considered less secure thanCertificate. Therefore, credentials generated byAdd-MoDCredentials -Type Passwordwill have a lifespan of 1 day while those generated byAdd-MoDCredentials -Type Certificatewill have a lifespan of 1 year - The proper cleanup of registered credentials, regardless of their active or expired state, is your responsibility. MfaOnDemand will not clean up any credentials but you might use
Get-MoDCredentialsto monitor them. - Microsoft Authenticator's Number Matching feature is NOT supported
MfaOnDemand leverages undocumented Entra ID MFA APIs! Use at your own risk!
The current functionality is the result of piecing together information from official Microsoft documentation regarding NPS extension/MFA Server/AD FS and similar solutions like these:
https://www.cyberdrain.com/automating-with-powershell-sending-mfa-push-messages-to-users/
https://lolware.net/blog/using-azure-mfa-onprem-ad/
https://www.entraneer.com/blog/entra/authentication/transactional-mfa-entra-id
Before you can make requests to the API, you must enable API Access and configure a RESTful API Client resource in the AuthPoint management UI [WatchGuard documentation].
# Send MFA OTP request
#Credential user is <AuthPoint_rw_access_ID> and password is <AuthPoint_rw_password>
$secret = Get-Credential
Invoke-MoDMfa -Provider AuthPoint -TenantId <AccountId>:<ResourceId> -ProviderArgs @{region=<cloud_region>; apikey=<api_key>} -Credential $secret -User <user> -Mode OTP <otp_code>
# Send MFA Push request
# Credential and ProviderArgs can be omitted because they were cached in the previous iteration
Invoke-MoDMfa -Provider AuthPoint -TenantId <AccountId>:<ResourceId> -User <user> -Mode PushInvoke-MoDMfa does not have any dependencies.
Add-MoDCredentials and Get-MoDCredentials require Microsoft.Graph module and Application.ReadWrite.All permissions on Entra ID Tenant.
I'd like to expand MfaOnDemand with additional MFA Providers and probably there's potential for more features within its scope.
If you have specific use cases or know of MFA service providers that you’d like to see implemented, please feel free to share your ideas or submit a PR.
Copyright 2024-2026 lestoilfante
GNU General Public License version 3 (GPLv3)