How to Report Azure AD Admin Accounts Not Protected by MFA

  1. # ReportMFAStatusAdmins.PS1
  2. #
  3. # Uses https://docs.microsoft.com/en-us/graph/api/userregistrationdetails-get
  4. # Example of how to use the User Registration Details API to report admin accounts that are not MFA-enabled.
  5. # https://github.com/12Knocksinna/Office365itpros/blob/master/ReportMFAStatusAdmins.PS1
  6.  
  7. Connect-MgGraph -Scopes UserAuthenticationMethod.Read.All, AuditLog.Read.All
  8. Select-MgProfile -Beta
  9. Write-Host "Retrieving information about users holding Microsoft 365 administratrive roles"
  10. $AdminRoleHolders = [System.Collections.Generic.List[Object]]::new()
  11. [array]$AdminRoles = Get-MgDirectoryRole | Select-Object DisplayName, Id
  12. ForEach ($Role in $AdminRoles) {
  13. [array]$RoleMembers = Get-MgDirectoryRoleMember -DirectoryRoleId $Role.Id | ? {$_.AdditionalProperties."@odata.type" -eq "#microsoft.graph.user"}
  14. ForEach ($Member in $RoleMembers) {
  15. $UserDetails = Get-MgUser -UserId $Member.Id
  16. $ReportLine = [PSCustomObject] @{
  17. User = $UserDetails.UserPrincipalName
  18. Id = $UserDetails.Id
  19. Role = $Role.DisplayName
  20. RoleId = $Role.Id }
  21. $AdminRoleHolders.Add($ReportLine) }
  22. }
  23. $AdminRoleHolders = $AdminRoleHolders | Sort User
  24. $Unique = $AdminRoleHolders | Sort User -Unique
  25.  
  26. # Create a slightly different report where each user has their assigned roles in one record
  27. $UniqueAdminRoleHolders = [System.Collections.Generic.List[Object]]::new()
  28. ForEach($User in $Unique) {
  29. $Records = $AdminRoleHolders | ? {$_.id -eq $User.Id}
  30. $AdminRoles = $Records.Role -join ", "
  31. $ReportLine = [PSCustomObject] @{
  32. Id = $User.Id
  33. User = $User.User
  34. Roles = $AdminRoles }
  35. $UniqueAdminRoleHolders.Add($ReportLine)
  36. }
  37. Write-Host ("There are {0} user accounts holding Microsoft 365 administrative roles." -f $UniqueAdminRoleHolders.count)
  38.  
  39. Write-Host "Scanning for MFA status"
  40. # Retrieve member accounts that are licensed
  41. [array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All
  42.  
  43. $UserRegistrationDetails = [System.Collections.Generic.List[Object]]::new()
  44. ForEach ($User in $Users) {
  45. Write-Host ("Checking admin roles and MFA status for {0}" -f $User.DisplayName)
  46. $Uri = "https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails/" + $User.Id
  47. $AccessMethodData = Invoke-MgGraphRequest -Uri $Uri -Method Get
  48. # Check if Admin
  49. $AdminAccount = $False; $AdminRolesHeld = $Null
  50. If ($user.id -in $UniqueAdminRoleHolders.Id) {
  51. $AdminAccount = $True
  52. $AdminRolesHeld = ($UniqueAdminRoleHolders | ? {$_.Id -eq $User.Id} | Select -ExpandProperty Roles) }
  53. $ReportLine = [PSCustomObject] @{
  54. User = $User.Displayname
  55. Id = $User.Id
  56. AdminAccount = $AdminAccount
  57. AdminRoles = $AdminRolesHeld
  58. MfaRegistered = $AccessMethodData.isMfaRegistered
  59. defaultMfaMethod = $AccessMethodData.defaultMfaMethod
  60. isMfaCapable = $AccessMethodData.isMfaCapable
  61. Methods = $AccessMethodData.MethodsRegistered -join ", " }
  62. $UserRegistrationDetails.Add($ReportLine)
  63. } #End ForEach
  64.  
  65. [Array]$ProblemAdminAccounts = $UserRegistrationDetails | ? {$_.AdminAccount -eq $True -and $_.MfaRegistered -eq $False }
  66. If ($ProblemAdminAccounts) {
  67. Cls
  68. Write-Host "The following accounts have administrative roles and are not enabled for MFA."
  69. Write-Host "-----------------------------------------------------------------------------"
  70. Write-Host ""
  71. $ProblemAdminAccounts | Select User, AdminRoles
  72. }
  73.  
  74. $UserRegistrationDetails | Export-Excel -Path c:\temp\UserRegistrationDetails.xlsx