Using MFA enabled accounts in PowerShell scripts

The use of multi-factor authentication (MFA) is growing by the day. More and more customers are enabling MFA for administrator accounts to protect their cloud environment a little bit more. But that also might affect your PowerShell scripts. In this post I want to point out how to deal with MFA enabled accounts in your PowerShell script.

Connecting to services

Before you can use cmdlets from modules like Azure PowerShell, Azure Active Directory and SharePoint Online you need to connect to these services first. Each of these services has its own “login” cmdlet. For example:

# Azure PowerShell
Login-AzureRMAccount

# Azure AD
Connect-AzureAD

# SharePoint Online
Connect-SPOService -Url https://octavie365-admin.sharepoint.com

These cmdlets also have a parameter Credential and you can pass a PSCredential object. This is handy when you need  to connect to multple services with the same credentials. One way to achieve this is to ask the username and password from the script.

image

$AdminUsername = Read-Host -Prompt "Azure/Office 365 Admin User Account"
$AdminPassword = Read-Host -Prompt "Password" -AsSecureString

$adminCredentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $AdminUsername, $AdminPassword

Login-AzureRmAccount -Credential $adminCredentials
Connect-AzureAD -Credential $adminCredentials 

And of course, you can also use

$adminCredentials = Get-Credential

to get the Windows PowerShell login popup:

image

 

Windows Credential Manager

If you don’t way to ask for credentials in the script, you can also use the Windows Credential Manager. You need to install the module CredentialManager for this.

https://www.powershellgallery.com/packages/CredentialManager/2.0

( I am not going to describe how to set this all up. Plenty of articles available, such as https://www.petri.com/managing-usernames-passwords-powershell-sharepoint-online )

Once set up, your script can look like this:

# Get credentials from the Credential Manager
$adminCredentials = Get-StoredCredentials -Target "MFADEMO"

Login-AzureRmAccount -Credential $adminCredentials

What about MFA enabled accounts?

In spite of all the advanced scripting above, it simply does not work with MFA enabled accounts. You will see errors like this

Login-AzureRmAccount : AADSTS50076: Due to a configuration change made by your administrator, or because you moved to a new location, you must use multi-factor authentication to access 'bla-bla'.

Connect-SPOService : The sign-in name or password does not match one in the Microsoft account system.

The only solution available today (that I know of) is to use the cmdlets to connect to your service without the parameter Credential. This will show you the Sign in to your account popup of that service and this login window has the support for MFA. For example:

image

image

image

Does this mean you have to throw all your scripts into the recycle bin? No, you are going to accept and embrace this.

It is what it is.

 

You can add a switch parameter to your own script to indicate MFA should be used. With that you can have a if-then-else construction.

[CMDLetBinding()]
Param(
    # Tenant Name
    [Parameter(Mandatory=$true,HelpMessage="Your tenant name. E.g. Mavention or Contoso")]
    [String]
    $TenantName,
    # Use MFA login
    [Switch]$MFA
)

$urlSPOAdmin = "https://$($TenantName)-admin.sharepoint.com"

if ( $MFA ) {
    Login-AzureRmAccount
    Connect-SPOService -Url $urlSPOAdmin
}
else {
    $AdminUsername = Read-Host -Prompt "Azure Admin User Account"
    $AdminPassword = Read-Host -Prompt "Password" -AsSecureString
        
    $adminCredentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $AdminUsername, $AdminPassword

    Login-AzureRmAccount -Credential $adminCredentials
    Connect-SPOService -Url $urlSPOAdmin -Credential $adminCredentials
}

Summary

As more and more customers are enabling multi-factor authentication (MFA) for administrator accounts, your PowerShell scripts may not work anymore. In case of MFA enabled accounts, you have to use the cmdlets to connect to your service without the parameter Credential. The Sign-In window has support for MFA.

Share

4 thoughts on “Using MFA enabled accounts in PowerShell scripts

  1. Sam

    Thanks for the tips! I was running into this issue while running to run power shell scripts against an Office 365 tenant with MFA enabled. Leaving out the credential parameter and letting it prompt for authentication worked great.

  2. John Langston

    I have a scheduled task (at night) executes a PS script that copies 400+ databases from prod to dev and creates a number of dev-specific accounts(AAD and Groups) and their permissions after the dev databases have copied. The copy step can be done with a non-AD account but the application of the dev-specific accounts must be done using an AAD account. MFA looks to break this template by requiring me to be there to provide and account and password information interactively. Am I missing something? Thanks for helping me see clearly.

    1. Octavie van Haaften Post author

      Hi John,

      Do I understand it correctly, that your daily scheduled script is running under the credentials (yours?) that has MFA enabled?
      Looks to me that this should be better some service account without MFA enabled and having sufficient permissions (read: not necessarily the Global Admin role) to run this process.

      grtz,
      Octavie

Leave a Reply

Your email address will not be published. Required fields are marked *