This is what I found out - corrections welcome:
- The information is logged internally, but not directly accessible to us as a customer.
- The Authentication methods tab of Microsoft Entra admin center User pages lists the user's registered Microsoft Authenticator instances but offers no way to get the time of last use of the listed instances. There is no way to distinguish between entries in the list that have the same Display name and Phone application version or to find out which of them refers to the instance presently installed on a specific phone or used in a specific authentication event.
- The Sign-in log records whether Microsoft Authenticator was used for a sign-in but does not contain any information that references the specific Authenticator instance used.
- Internally, Entra keeps a user attribute named "StrongAuthenticationPhoneAppDetail" which contains the list of Authentication methods but which much more detail than what it displays on the user page. Most notably, it contains an "Id" field and a field "LastAuthenticatedTimestamp" showing the last time this Authentication method was used.
- There doesn't seem to be a direct way to query a user's "StrongAuthenticationPhoneAppDetail" attribute, but its current and previous value are disclosed through an Update user event in the Audit log each time the user actually uses one of the methods.
So my current solution is the KQL query:
AuditLogs
| where TimeGenerated > ago(90d)
| where OperationName == @"Update user"
| where parse_json(InitiatedBy)["app"]["displayName"] == "Azure MFA StrongAuthenticationService"
| extend TargetResources = parse_json(TargetResources)
| mv-expand TargetResources
| extend userPrincipalName = TargetResources["userPrincipalName"], modifiedProperties = TargetResources["modifiedProperties"]
| summarize arg_max(TimeGenerated, *) by tostring(userPrincipalName)
| mv-expand modifiedProperties
| where parse_json(modifiedProperties)["displayName"] == 'StrongAuthenticationPhoneAppDetail'
| extend newValue = tostring(parse_json(modifiedProperties)["newValue"])
| mv-expand newValue = parse_json(newValue)
| extend DeviceName = parse_json(newValue)["DeviceName"], AppVersion = parse_json(newValue)["PhoneAppVersion"], LastAuthenticatedTimestamp = parse_json(newValue)["LastAuthenticatedTimestamp"]
| project TimeGenerated, UPN = tolower(userPrincipalName), DeviceName, AppVersion, LastUse = tostring(LastAuthenticatedTimestamp)
| order by UPN asc, LastUse desc
This gives me a partially outdated and incomplete list of Authenticators for each user with date of last use. The TimeGenerated column tells me how outdated each line is. It is missing those users who didn't do any MFA within the last 90 days.
For the Authenticators which haven't been used for a long time (say, more than a year) I then open the user's Authentication methods tab in the Entra admin center and try to identify it in the list. If I don't find it I assume it has been removed since the entry's TimeGenerated. If I find more than one entry with the same name and app version, I come back after a month or so, hoping that the instance in active use has received an update so that I can then distinguish it by its app version.
Hope it helps someone.