Get MFA Status with PowerShell

One of the reports that I really miss in the Microsoft 365 Admin Center is a clear overview of the MFA status for each user. Yes, you can check it sort of under Active Users > Multi-Factor Authentication, but that is not really user-friendly. An easier way is to use PowerShell to get the MFA Status for each user.

New Microsoft 365 Tenants that are created after 22 October 2019 will have MFA enabled by default for all users as part of the security defaults. But with older tenants, you will need to manually enable MFA for each user. The challenge is to make sure all users have enabled it and keep track of it.

With PowerShell, we can easily get the MFA Status of all users and create an Excel list with all the details we need. I have created a script that can do a couple of things to check the MFA status of your users:

  • List the MFA Status of all users
  • Get all the users that don’t have MFA enabled
  • Check the MFA status of a single user
  • Check if MFA is enforced
  • Checks if a user is admin or not
  • Get only the licensed and enabled users

At the end of the article you will find the complete script.

Get the MFA Status with PowerShell

With PowerShell, we can easily get the MFA Status of all our Office 365 users. The basis for the script is the Get-MsolUser cmdlet, which gets the users from the Azure Active Directory.

Get-MsolUser returns all the user details, including the parameter StrongAuthenticationMethods. This parameter will list all the strong authentication methods that a user is using. If this parameter is set, then we know that the user is using MFA.

Requirements

You need to have the MsolService module installed to use this script. Make sure you are connected before you run the script

Connect-MsolService

Getting a list of all users and there MFA Status

You can just run the script without any parameters to get a list with all the users and their MFA Status. The script will check if the user is an admin and will list the default MFA type that the user has set.

You can export the result on the screen or to an CSV file if you like.

# Make sure you are connected to MsolService
Get-MFAStatus | FT

# Or if you want an excel file
Get-MFAStatus | Export-CSV c:\temp\mfastatus.csv -noTypeInformation
Get MFA Status PowerShell

Get only the users without MFA

If you have a large tenant then you probably only want to get the users without MFA. You can use the switch withOutMFAOnly for this.

Get-MFAStatus -withOutMFAOnly

Check the MFA Status of admins

Admins should have MFA enable without a doubt. To quickly check the status of all your admin accounts you can use the switch adminsOnly

Get-MFAStatus -adminsOnly

Check the MFA status on a selection of users

The script also allows you to check the MFA Status of a single user or multiple users.

Get-MFAStatus -UserPrincipalName '[email protected]'

If you want to check the status of a single department for example, then you can do the following:

Get-MsolUser -Department 'Finance' | ForEach-Object { Get-MFAStatus $_.UserPrincipalName }

The complete script

You can find the complete script here below or you can get it here from my Github.

Function Get-MFAStatus {
<#
  .Synopsis
    Get the MFA status for all users or a single user.

  .DESCRIPTION
    This script will get the Azure MFA Status for your users. You can query all the users, admins only or a single user.
   
		It will return the MFA Status, MFA type (

  .NOTES
    Name: Get-MFAStatus
    Author: R. Mens - LazyAdmin.nl
    Version: 1.0
    DateCreated: jan 2021
    Purpose/Change: Initial script development
		Thanks to: Anthony Bartolo

  .LINK
    https://lazyadmin.nl

  .EXAMPLE
    Get-MFAStatus

    Get the MFA Status of all enabled and licensed users and check if there are an admin or not

  .EXAMPLE
    Get-MFAStatus -UserPrincipalName '[email protected]','[email protected]'

    Get the MFA Status for the users John Doe and Jane Doe

  .EXAMPLE
    Get-MFAStatus -withOutMFAOnly

    Get only the licensed and enabled users that don't have MFA enabled

  .EXAMPLE
    Get-MFAStatus -adminsOnly

    Get the MFA Status of the admins only

  .EXAMPLE
    Get-MsolUser -Country "NL" | ForEach-Object { Get-MFAStatus -UserPrincipalName $_.UserPrincipalName }

    Get the MFA status for all users in the Country The Netherlands. You can use a similar approach to run this
    for a department only.

  .EXAMPLE
    Get-MFAStatus -withOutMFAOnly | Export-CSV c:\temp\userwithoutmfa.csv -noTypeInformation

    Get all users without MFA and export them to a CSV file
#>
  [CmdletBinding(DefaultParameterSetName="Default")]
  param(
    [Parameter(
      Mandatory = $false,
      ValueFromPipeline = $true,
      ValueFromPipelineByPropertyName = $true,
      ParameterSetName  = "UserPrincipalName",
      Position = 0
      )]
    # Enter a single UserPrincipalName or a comma separted list of UserPrincipalNames
    [string[]]$UserPrincipalName,

    [Parameter(
      Mandatory = $false,
      ValueFromPipeline = $false,
      ParameterSetName  = "AdminsOnly",
      Position = 0
    )]
    # Get only the users that are an admin
    [switch]$adminsOnly = $false,

    [Parameter(
      Mandatory         = $false,
      ValueFromPipeline = $false,
      ParameterSetName  = "AllUsers"
    )]
    # Set the Max results to return
    [int]$MaxResults = 1000,

    [Parameter(
      Mandatory         = $false,
      ValueFromPipeline = $false,
      ParameterSetName  = "AllUsers"
    )]
    # Check only the MFA status of users that have license
    [switch]$IsLicensed = $true,

    [Parameter(
      Mandatory         = $false,
      ValueFromPipeline = $true,
      ValueFromPipelineByPropertyName = $true,
      ParameterSetName  = "AllUsers"
    )]
    # Get only the users that don't have MFA enabled
    [switch]$withOutMFAOnly = $false,

    [Parameter(
      Mandatory         = $false,
      ValueFromPipeline = $false
    )]
    # Check if a user is an admin. Set to $false to skip the check
    [switch]$listAdmins = $true
  )

Begin {
  # Get all licensed admins
  $admins = $null

  if (($listAdmins) -or ($adminsOnly)) {
    $admins = Get-MsolRoleMember -RoleObjectId $(Get-MsolRole -RoleName "Company Administrator").ObjectId | Where-Object {$_.isLicensed -eq $true} | Select-Object ObjectId,EmailAddress
  }
}

Process {
  # Check if a UserPrincipalName is given
  # Get the MFA status for the given user(s) if they exist
  if ($PSBoundParameters.ContainsKey('UserPrincipalName')) {
    foreach ($user in $UserPrincipalName) {
			try {
        $MsolUser = Get-MsolUser -UserPrincipalName $user -ErrorAction Stop

        [PSCustomObject]@{
          DisplayName       = $MsolUser.DisplayName
          UserPrincipalName = $MsolUser.UserPrincipalName
          isAdmin           = if ($listAdmins -and $admins.EmailAddress -match $MsolUser.UserPrincipalName) {$true} else {"-"}
          MFAEnabled        = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
          MFAType           = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
					MFAEnforced       = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
        }
      }
			catch {
				[PSCustomObject]@{
					DisplayName       = " - Not found"
					UserPrincipalName = $User
					isAdmin           = $null
					MFAEnabled        = $null
				}
			}
    }
  }
  # Get only the admins and check their MFA Status
  elseif ($adminsOnly) {
    foreach ($admin in $admins) {
      $MsolUser = Get-MsolUser -ObjectId $admin.ObjectId | Sort-Object UserPrincipalName -ErrorAction Stop

      [PSCustomObject]@{
        DisplayName       = $MsolUser.DisplayName
        UserPrincipalName = $MsolUser.UserPrincipalName
        isAdmin           = $true
        MFAEnabled        = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
        MFAType           = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
				MFAEnforced       = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
      }
    }
  }
  # Get the MFA status from all the users
  else {
    $MsolUsers = Get-MsolUser -EnabledFilter EnabledOnly -MaxResults $MaxResults | Where-Object {$_.IsLicensed -eq $isLicensed} | Sort-Object UserPrincipalName
      foreach ($MsolUser in $MsolUsers) {

        if ($withOutMFAOnly) {
          # List only the user that don't have MFA enabled
          if (-not($MsolUser.StrongAuthenticationMethods)) {

            [PSCustomObject]@{
              DisplayName       = $MsolUser.DisplayName
              UserPrincipalName = $MsolUser.UserPrincipalName
              isAdmin           = if ($listAdmins -and $admins.EmailAddress -match $MsolUser.UserPrincipalName) {$true} else {"-"}
              MFAEnabled        = $false
              MFAType           = "-"
							MFAEnforced       = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
            }
          }
        }else{
          [PSCustomObject]@{
            DisplayName       = $MsolUser.DisplayName
            UserPrincipalName = $MsolUser.UserPrincipalName
            isAdmin           = if ($listAdmins -and $admins.EmailAddress -match $MsolUser.UserPrincipalName) {$true} else {"-"}
            MFAEnabled        = if ($MsolUser.StrongAuthenticationMethods) {$true} else {$false}
            MFAType           = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType
						MFAEnforced       = if ($MsolUser.StrongAuthenticationRequirements) {$true} else {"-"}
          }
        }
      }
    }
  }
}

Wrapping up

If you found this script useful, then please share it. If you have any questions then just drop a comment below.

Get more stuff like this

IT, Office365, Smart Home, PowerShell and Blogging Tips

I hate spam to, so you can unsubscribe at any time.

2 thoughts on “Get MFA Status with PowerShell”

  1. This is pretty great, thank you. I’m attempting to get a list of users with a specific Strong Authentication Method Type set specifically to “PhoneAppNotification”. As it turns out, Microsoft offers users the ability to put their cell phone numbers on their accounts, which get registered as a Strong Authentication Method, even when MFA isnt configured. Because of that I have thousands of users that get returned when basic Strong Authentication queries are run.

    • Hi Jason,

      You can use the following code to only list the users with PhoneAppNotification:


      $msolUsers = get-msoluser -EnabledFilter EnabledOnly -MaxResults 1000

      foreach ($MsolUser in $MsolUsers) {
      $methodType = $MsolUser.StrongAuthenticationMethods | Where-Object {$_.IsDefault -eq $true} | Select-Object -ExpandProperty MethodType

      # List only the user that don't have MFA enabled
      if ($methodType -eq 'PhoneAppNotification') {
      write-host $MsolUser.UserPrincipalName
      }
      }

Leave a Comment

0 Shares
Tweet
Pin
Share
Share