O365 Secure Score & Azure Automation (Part 3) – Global Admin with MFA Disabled Report

If you would like to read the other parts of this article series, please go to:


Long time, no see

It’s been over a month since last article. A month with unusual good weather in Denmark, which has made sitting in front of a computer non-ideal… off-hours 🙂

In this episode…

It’s finally time to review the most important precaution: making sure global admins are secured with multi-factor authentication.

A straight forward task.

At Microsoft Ignite 2017, Alex Weinert presented following slide. Please note the last line.

Video: https://www.youtube.com/watch?v=62144uFy-wA


The challenge

The saying goes: “admitting you have a problem is the first step in fixing the problem”. But what if you don’t know you have a problem?

What if you think every Global Admin has MFA enabled because you enforced it once.

What if your Global Admins has created new Global Admins without enabling MFA for those new accounts?

And what if, let’s say, you or another admin temporarily disabled MFA for one other another reason? Admitted. I’ve done that myself, and then forgot about it.

One of the very few reasons to not enable MFA on a Global Admin: You have a third-party service or a script which require an Azure AD service account with Global Admin rights.

Because a service or script cannot respond to the MFA challenge, MFA it-self would be… challenging.

How to deal with it, today

Currently, there is only three build-in ways to check if all your admins have MFA enabled:

A: Go into the legacy-ish Azure AD MFA portal and review MFA for Global Admins

B: Go into Secure Score and check the score for “Enable MFA for all Global Admins”

C: Open PowerShell, sign-in to AAD/MSOL with your Global Admin account, complete the MFA challenge, run a PowerShell cmdlet or two.

You must do one (or more) of above occasionally – manually. And, if you find any account with a valid reason of not having it enabled, you must filter those – manually.



Azure Automation Account available

Take a look in the first article. Please provision an account before going any further.

Create Azure Automation Credential

If you haven’t already created one, do so – please follow the instructions in this article.

Exchange Online Service Account with mailbox or another available mail relay service

We need a SMTP of some kind when sending out reports. I recommend using a mailbox in Exchange Online, but you are free to use something else.

For this to work with Exchange Online the user account requires at least an Exchange Online Plan 1 license.

If using a third-party solution, it has to support authentication relay. If not, you must modify the runbook code.


Create Office 365 User Admin Service Account

As always, we want the service account performing the actions to have least privilege as possible.

Unfortunately, Office 365 – on tenant level – doesn’t provide a granular access control management for admin rights. We have following account types with less permissions than Global Admin:

  • Billing administrator
  • Exchange administrator
  • SharePoint administrator
  • Password administrator
  • Skype for Business administrator
  • Service administrator
  • User management administrator
  • Reports reader
  • Dynamics 365 service administrator
  • Power BI administrator

The only administrator type that can get the MFA-state of an account is User management administrators.

A service account with User management administrator rights is much safer than granting Global Admin rights.

But remember: the account will, among other things, have permissions to create, modify and remove non-global admin accounts. Handle with care!

A full list of different admin rights can be found here.

Now – go to your Office 365 admin portal and create a user.

When creating the user, select Customized administrator in the Roles section and tick User Management administrators.

No Office 365 license is required for this service account.

NOTE: If your Office tenant has “password expire” enabled, you should disable password expiration on this user.


Create Azure Automation Credentials

As in past articles we want to use the build-in credential vault of Azure Automation store service account username and password.

Office 365 User Admin Service Account credentials

Go to the automation account, select Credentials (under Shared Resources) and click Add a credential.

Fill the credential form. Remember the Name – you need that later on when executing the script.

SMTP relay authentication credentials

The same goes for this one: Go to the automation account, select “Credentials” (under Shared Resources) and click “Add a credential”.

Fill the credential form. Remember the Name – you need that later on when executing the script.


Add MSOnline PowerShell Module to Azure Automation Account

Now you might think: “why not AzureAD PowerShell module? It make use of the Graph API!”

The newest general available module to manage Azure AD – also known as Azure AD Module v2 – is not able to retrieve sufficient multi-factor information from a user account.

Luckily, we still have MSOnline.

Example of output

Go to the Azure Automation account, select Modules and click Browse Gallery

Search for MSOnline, select the module by the same name and click Import.

Wait a minute or so until the module is imported.

Bonus Info: #requires doesn’t work in Azure Automation Runbooks

While writing and testing the part of the runbook where Import-Module is executed, I thought: “Maybe I could use ‘#requires -module MSOnline’ in the beginning of the runbook, to verify whether the module is present or not?”

Windows PowerShell supports more attributes of input parameters than those listed here, like validation, aliases, and parameter sets. However, Azure Automation currently supports only the preceding input parameters.
– docs.microsoft.com

And #required is neither supported / working. I tried to run a very early version of the runbook with “#requires -module MSOnline“ in the beginning on a Automation Account without MSOnline imported.

The result:

The script begins even though MSOnline isn’t present in the module list.


Import Azure Automation Runbook

Please review the prerequisites further up in this article if you don’t have an Azure Automation account nor created Azure Automation Credentials.

Go to the Azure Automation account, select Runbooks and click Browse Gallery

In the Filter pane, click the drop-down, select PowerShell Gallery and click OK.

Search for O365-GlobalAdminMfaDisabledReport select the script.

Please review the in-script documentation or GitHub ReadMe.

Click Import. Change the name if you want to. Click OK.

Click Edit and review the script.

Click Save.


Test Runbook

Click “Test pane”.

Fill the parameters:

  • AutomationPSCredentialName
  • ExcludeUserAccount
  • SendReport
  • ReportSmtpServerAddress
  • ReportSmtpServerPort
  • ReportSmtpFromAddress
  • ReportSmtpToAddress
  • ReportSmtpPSCredentialName
  • EnableVerbose

It could be something like this:

Parameter Value
AutomationPSCredentialName Office 365 User Management Service Account
ExcludeUserAccount [“serviceaccount-a@domain.onmicrosoft.com”]
SendReport true
ReportSmtpServerAddress smtp.office365.com
ReportSmtpServerPort 587
ReportSmtpFromAddress Office 365 Automation <noreply@domain.com>
ReportSmtpToAddress [“abc@domain.com”, “xyz@domain.com”]
ReportSmtpPSCredentialName Office 365 Automation Mailbox
EnableVerbose true

If any doubts, please check the GitHub project ReadMe!

Click “Start” and wait for script to complete

In the example above, the runbook discovered global admins with MFA disabled where one is excluded. It then sent a report to one recipient.

And the report is received in the To inbox.

And the attachment:


Deploy & Schedule Runbook

In the edit pane click Publish and Yes.

Select Schedules under Resources and then click Add a schedule.

You can select the schedule created in the last article, or you can create a new one. It’s all up to you.

When a schedule is created/selected, fill the parameters of the schedule. Click OK.

If you want to test the published runbook, go to the overview of the runbook and click Start and enter the same parameters as in the schedule. Then review the Output.


You should now receive an email notification whenever one or more global admins has MFA disabled – except those you have excluded.

Hopefully your Secure Score has increased further.

Note: for some reason, my tenant is “stuck” on the score 16/50 on the “Enable MFA for all global admins”, even though all of my three admins has MFA enabled :-/

In the next article, we will search for unused users and global admins and generate a weekly report if any is found – yet again with help from Azure Automation.

If you would like to read the other parts of this article series, please go to:

Soren is an IT Professional based in Copenhagen, Denmark.

His primary work areas are system design, deployment, migration and administration of business-critical IT infrastructure.

Leave a Reply

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