Forum Discussion

StevenRPF's avatar
StevenRPF
Brass Contributor
Mar 28, 2023

Get MFAStatus with API

Hi,

 

I'm trying to get a report for the MFA status for all my tenant users.

# Replace the values in the following variables with your own
$clientId = "your_client_id_here"
$clientSecret = "your_client_secret_here"
$tenantId = "your_tenant_id_here"

# Authenticate using Microsoft Graph API
$tokenBody = @{
    Grant_Type    = "client_credentials"
    Scope         = "https://graph.microsoft.com/.default"
    Client_Id     = $clientId
    Client_Secret = $clientSecret
}
$tokenResponse = Invoke-RestMethod -Method POST -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body $tokenBody
$accessToken = $tokenResponse.access_token

# Retrieve all users in the tenant
$users = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/users" -Headers @{Authorization = "Bearer $accessToken"}

# Loop through each user and retrieve their MFA status
foreach ($user in $users.value) {
    $userId = $user.id
    $mfaStatus = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/users/$userId/authentication/strongAuthenticationMethods" -Headers @{Authorization = "Bearer $accessToken"}
    $mfaEnabled = $mfaStatus.value | Where-Object {$_.state -eq "enabled"}

    Write-Output "$($user.displayName) - MFA Enabled: $($mfaEnabled -ne $null)"
}

 

I got this script but I'm always getting an error when I'm trying to execute it ... error is : 

Line |
  17 |  $users = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft. …
     |           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     | {"error":{"code":"Authorization_RequestDenied","message":"Insufficient privileges to complete the
     | operation.","innerError":{"date":"2023-03-28T00:21:46","request-id":"d929a2d8-ca16-44b4-af0b-4d514c15ea78","client-request-id":"d929a2d8-ca16-44b4-af0b-4d514c15ea78"}}}

 

In my API permission, I've double check to be sur all permission are ok :

  • UserAuthenticationMethod.Read.All or UserAuthenticationMethod.ReadWrite.All (for Microsoft Graph API v1.0) OR AuthenticationMethod.Read.All or AuthenticationMethod.ReadWrite.All (for Microsoft Graph API beta)
  • User.Read.All or User.ReadWrite.All (for Microsoft Graph API v1.0) OR Directory.Read.All or Directory.ReadWrite.All (for Microsoft Graph API beta)

I've check again my clientID-clientSecret-TenanID and seems to be good : How to be sure this is OK? Any log in AzureAD to check if at least my script is able to authenticate?

 

Thanks in advance!

10 Replies

  • Not sure where you got this code, but there is no /users/$userId/authentication/strongAuthenticationMethods endpoint. The correct one should be /users/$userId/authentication/Methods, or if you are looking for the report instead, /reports/credentialUserRegistrationDetails.

    The token part looks fine, but make sure the permissions are correctly reflected in the obtained access token. You can parse it with tools such as jwt.ms.
    • StevenRPF's avatar
      StevenRPF
      Brass Contributor
      To be honnest, this code is from ChatGPT! πŸ™‚ You understand that I'm not a professionnal in powershell!! πŸ™‚

      I tried you modification and same error at same line .... like if I have an authorization problem.

      Can you give me a cue to check if my authentication and permission are good with the API?

      THanks
      • VasilMichev's avatar
        VasilMichev
        MVP
        ChatCPT is smoking something good, again... πŸ™‚

        Let's start with the basics, did you create an app registration and grant the permissions? In other words, are you populating the variables with the correct values?

        $clientId = "your_client_id_here"
        $clientSecret = "your_client_secret_here"
        $tenantId = "your_tenant_id_here"

        Double- and triple-check if everything is OK there. Once you run the following:

        $accessToken = $tokenResponse.access_token

        you can do another check - decode the token and make sure the required permissions are correctly reflected therein. To do so, copy the token and head over to https://jwt.ms to decode it. You can copy it directly via:

        $accessToken | clip

Resources