Report on MFA Status with Conditional Access

%3CLINGO-SUB%20id%3D%22lingo-sub-1420735%22%20slang%3D%22en-US%22%3EReport%20on%20MFA%20Status%20with%20Conditional%20Access%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1420735%22%20slang%3D%22en-US%22%3E%3CP%3EIs%20there%20any%20effective%20way%20to%20get%20a%20report%20of%20the%20actual%20MFA%20state%20of%20your%20users%3F%3C%2FP%3E%3CP%3EI%20mean%2C%20the%20individual%20MFA%20state%20as%20well%20as%20MFA%20enabled%20via%20Conditional%20Access.%3C%2FP%3E%3CP%3EIt's%20easy%20to%20report%20on%20the%20individual%20MFA%20state.%20You%20get%20nice%20results%3A%20Enabled%2C%20Disabled%2C%20Enforced...%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EHowever%2C%20if%20MFA%20is%20enabled%20via%20Conditional%20Access%20I%20can't%20seem%20to%20find%20an%20effective%20way%20to%20report%20on%20them.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EBelow%20Powershell%20snippet%20is%20the%20closest%20I%20can%20get.%3CBR%20%2F%3EIt%20will%20check%20if%20MFA%20is%20enabled%20individually.%20If%20not%2C%20it%20will%20check%20the%20%22StrongAuthenticationMethods.IsDefault%22%20attribute%20and%20report%20on%20that.%3C%2FP%3E%3CP%3EBut%20this%20is%20not%20always%20accurate%2C%20because%20if%20the%20%22Phone%22%20or%20%22Alternate%20Phone%22%20are%20configured%20in%20the%20Azure%20user%20object%2C%20it%20will%20still%20report%20it%20here%20even%20if%20the%20user%20is%20not%20member%20of%20a%20Conditional%20Access%20policy.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThere%20is%20a%20built-in%20Azure%20report%20for%20this%2C%20but%20it%20is%20completely%20incorrect.%20It%20says%20that%2C%20for%20instance%2C%20I'm%20not%20enabled%20for%20MFA%20even%20though%20I'm%20enabled%20for%20the%20last%206%20years.%3C%2FP%3E%3CP%3EReport%3A%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fportal.azure.com%2F%23blade%2FMicrosoft_AAD_IAM%2FAuthMethodsOverviewBlade%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fportal.azure.com%2F%23blade%2FMicrosoft_AAD_IAM%2FAuthMethodsOverviewBlade%3C%2FA%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EHas%20anyone%20figured%20this%20out%20yet%3F%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-powershell%22%3E%3CCODE%3E%24user%20%3D%20get-msoluser%20-UserPrincipalName%20yourUserName%40contoso.com%0A%0A%24StrongAuthenticationMethodsresult%20%3D%20%24user.StrongAuthenticationMethods%20%7C%20Select-Object%20MethodType%2C%20IsDefault%0A%0A%5BPSCustomObject%5D%40%7B%0A%20%20UserPrincipalName%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.UserPrincipalName%0A%20%20ObjectID%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.objectid%0A%20%20DisplayName%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.DisplayName%0A%20%20AuthEmail%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.StrongAuthenticationUserDetails.Email%0A%20%20AuthPhoneNumber%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.StrongAuthenticationUserDetails.PhoneNumber%0A%20%20PhoneDeviceName%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.StrongAuthenticationPhoneAppDetails.DeviceName%0A%20%20AuthAltPhone%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20%24user.StrongAuthenticationUserDetails.AlternativePhoneNumber%0A%0A%20%20State%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20if%20(%24user.StrongAuthenticationRequirements.State%20-ne%20%24null)%20%7B%20%24user.StrongAuthenticationRequirements.State%20%7D%20elseif%20(%20%24user.StrongAuthenticationMethods.IsDefault%20-eq%20%24true)%20%7B%20%22ConditionalAccess%20(%24((%24user.StrongAuthenticationMethods%7C%20Where%20IsDefault%20-eq%20%24True).MethodType))%22%20%7D%20else%20%7B%20%22Disabled%22%20%7D%0A%0A%20%20PhoneAppNotification%20%20%20%20%20%20%20%20%20%20%3D%20if%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22PhoneAppNotification%22%20%7D)%20%7B%20%24true%20%7D%20else%20%7B%20%24false%20%7D%0A%20%20PhoneAppNotificationIsDefault%20%3D%20IF%20(%20%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22PhoneAppNotification%22%20%7D).isDefault%20-eq%20%22True%22)%20%7B%20%24true%20%7D%20Else%20%7B%20%24false%20%7D%0A%0A%20%20PhoneAppOTP%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20if%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22PhoneAppOTP%22%20%7D)%20%7B%20%24true%20%7D%20else%20%7B%20%24false%20%7D%0A%20%20PhoneAppOTPIsDefault%20%20%20%20%20%20%20%20%20%20%3D%20IF%20(%20%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22PhoneAppOTPIsDefault%22%20%7D).isDefault%20-eq%20%22True%22)%20%7B%20%24true%20%7D%20Else%20%7B%20%24false%20%7D%0A%0A%20%20TwoWayVoiceMobile%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20if%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22TwoWayVoiceMobile%22%20%7D)%20%7B%20%24true%20%7D%20else%20%7B%20%24false%20%7D%0A%20%20TwoWayVoiceMobileIsDefault%20%20%20%20%3D%20IF%20(%20%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22TwoWayVoiceMobileIsDefault%22%20%7D).isDefault%20-eq%20%22True%22)%20%7B%20%24true%20%7D%20Else%20%7B%20%24false%20%7D%0A%0A%20%20OneWaySMS%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%3D%20if%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22OneWaySMS%22%20%7D)%20%7B%20%24true%20%7D%20else%20%7B%20%24false%20%7D%0A%20%20OneWaySMSIsDefault%20%20%20%20%20%20%20%20%20%20%20%20%3D%20IF%20(%20%20(%24StrongAuthenticationMethodsresult%20%7C%20Where-Object%20%7B%20%24_.MethodType%20-eq%20%22OneWaySMSIsDefault%22%20%7D).isDefault%20-eq%20%22True%22)%20%7B%20%24true%20%7D%20Else%20%7B%20%24false%20%7D%0A%7D%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1420735%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EConditional%20Access%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3Emfa%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EMulti-Factor%20Authentication%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1423198%22%20slang%3D%22en-US%22%3ERe%3A%20Report%20on%20MFA%20Status%20with%20Conditional%20Access%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1423198%22%20slang%3D%22en-US%22%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F9558%22%20target%3D%22_blank%22%3E%40Aldin%20Turcinovic%3C%2FA%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI've%20been%20using%20this%20script%2C%20it%20reports%20on%20users%20that%20are%20mfa%20enforced%20via%20CA%20policy%20and%20have%20a%20disabled%20mfa%20user%20state.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fgallery.technet.microsoft.com%2Foffice%2FExport-Office-365-Users-81747c73%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgallery.technet.microsoft.com%2Foffice%2FExport-Office-365-Users-81747c73%3C%2FA%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1423747%22%20slang%3D%22en-US%22%3ERe%3A%20Report%20on%20MFA%20Status%20with%20Conditional%20Access%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1423747%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F379369%22%20target%3D%22_blank%22%3E%40n3vers%3C%2FA%3E%26nbsp%3B%3CBR%20%2F%3EThanks.%20I%20already%20came%20across%20that%20script.%3C%2FP%3E%3CP%3EIt%20basically%20does%20the%20same%20as%20mine.%3C%2FP%3E%3CP%3EIt's%20not%20accurate.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20there%20is%20a%20Conditional%20Access%20policy%2C%20but%20due%20to%20some%20conditions%20a%20particular%20account%20is%20not%20affacted%20by%20it%20and%20he%20has%20an%20Authentication%20Phone%20configured%2C%20the%20script%20(like%20mine)%20will%20report%20that%20MFA%20is%20enabled%20even%20though%20it's%20not%20enforced.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EWe%20have%20a%20couple%20of%20these%20accounts%20in%20our%20environment.%3C%2FP%3E%3CP%3EWhile%20everything%20is%20under%20control%20here%2C%20I%20wanted%20to%20have%20a%20reliable%20report%20where%20I%20can%20look%20at%20occasionally%20to%20identify%20such%20accounts%20if%20they%2C%20for%20some%20reason%2C%20slip%20through.%3C%2FP%3E%3C%2FLINGO-BODY%3E
Highlighted
Occasional Contributor

Is there any effective way to get a report of the actual MFA state of your users?

I mean, the individual MFA state as well as MFA enabled via Conditional Access.

It's easy to report on the individual MFA state. You get nice results: Enabled, Disabled, Enforced...

 

However, if MFA is enabled via Conditional Access I can't seem to find an effective way to report on them.

 

Below Powershell snippet is the closest I can get.
It will check if MFA is enabled individually. If not, it will check the "StrongAuthenticationMethods.IsDefault" attribute and report on that.

But this is not always accurate, because if the "Phone" or "Alternate Phone" are configured in the Azure user object, it will still report it here even if the user is not member of a Conditional Access policy.

 

There is a built-in Azure report for this, but it is completely incorrect. It says that, for instance, I'm not enabled for MFA even though I'm enabled for the last 6 years.

Report: https://portal.azure.com/#blade/Microsoft_AAD_IAM/AuthMethodsOverviewBlade

 

Has anyone figured this out yet?

 

 

 

 

 

$user = get-msoluser -UserPrincipalName yourUserName@contoso.com

$StrongAuthenticationMethodsresult = $user.StrongAuthenticationMethods | Select-Object MethodType, IsDefault

[PSCustomObject]@{
  UserPrincipalName             = $user.UserPrincipalName
  ObjectID                      = $user.objectid
  DisplayName                   = $user.DisplayName
  AuthEmail                     = $user.StrongAuthenticationUserDetails.Email
  AuthPhoneNumber               = $user.StrongAuthenticationUserDetails.PhoneNumber
  PhoneDeviceName               = $user.StrongAuthenticationPhoneAppDetails.DeviceName
  AuthAltPhone                  = $user.StrongAuthenticationUserDetails.AlternativePhoneNumber

  State                         = if ($user.StrongAuthenticationRequirements.State -ne $null) { $user.StrongAuthenticationRequirements.State } elseif ( $user.StrongAuthenticationMethods.IsDefault -eq $true) { "ConditionalAccess ($(($user.StrongAuthenticationMethods| Where IsDefault -eq $True).MethodType))" } else { "Disabled" }

  PhoneAppNotification          = if ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "PhoneAppNotification" }) { $true } else { $false }
  PhoneAppNotificationIsDefault = IF (  ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "PhoneAppNotification" }).isDefault -eq "True") { $true } Else { $false }

  PhoneAppOTP                   = if ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "PhoneAppOTP" }) { $true } else { $false }
  PhoneAppOTPIsDefault          = IF (  ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "PhoneAppOTPIsDefault" }).isDefault -eq "True") { $true } Else { $false }

  TwoWayVoiceMobile             = if ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "TwoWayVoiceMobile" }) { $true } else { $false }
  TwoWayVoiceMobileIsDefault    = IF (  ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "TwoWayVoiceMobileIsDefault" }).isDefault -eq "True") { $true } Else { $false }

  OneWaySMS                     = if ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "OneWaySMS" }) { $true } else { $false }
  OneWaySMSIsDefault            = IF (  ($StrongAuthenticationMethodsresult | Where-Object { $_.MethodType -eq "OneWaySMSIsDefault" }).isDefault -eq "True") { $true } Else { $false }
}

 

 

 

 

 

2 Replies
Highlighted

 

@Aldin Turcinovic 

I've been using this script, it reports on users that are mfa enforced via CA policy and have a disabled mfa user state.

 

https://gallery.technet.microsoft.com/office/Export-Office-365-Users-81747c73

Highlighted

@n3vers 
Thanks. I already came across that script.

It basically does the same as mine.

It's not accurate.

 

If there is a Conditional Access policy, but due to some conditions a particular account is not affacted by it and he has an Authentication Phone configured, the script (like mine) will report that MFA is enabled even though it's not enforced.

 

We have a couple of these accounts in our environment.

While everything is under control here, I wanted to have a reliable report where I can look at occasionally to identify such accounts if they, for some reason, slip through.