From the Microsoft Entra Admin center on the left for monitoring and health some times it is is hidden under show more. under that tab is Log analyst
Large number of failed authentications - If a user account has a large amount of failed authentications in a short time period, it could be a sign of a brute force or password spray attack. The following KQL example will return all users that have 10+ failed password attempts in the last 24 hours.
SigninLogs
| where TimeGenerated > ago (24hrs)
| where ResultType == "50126"
| summarize event_count = count() by UserPrincipalName
| where event_count > 9
| project UserPrincipalName, event_count
MFA fatigue attack - An MFA fatigue attack is where the end user is repeatedly bombarded with MFA requests in the hope they will approve one. The number match experience has largely mitigated this type of attack but this is also an indicator that a user's password may have been compromised so needs to be reviewed urgently. The following KQL example will return users that have had 5+ MFA failures or device authentication failures in the last 24 hours.
SigninLogs
| where TimeGenerated > ago (24hrs)
| where ResultType == "500121" or ResultType == "50155" or ResultType == "50158"
| summarize event_count = count() by UserPrincipalName
| where event_count > 4
| project UserPrincipalName, event_count
More Detailed
SigninLogs
| where ResultType in ("500121", "50155", "50158")
| summarize
event_count = count(),
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
IPs = make_set(IPAddress),
Apps = make_set(AppDisplayName)
by UserPrincipalName
| where event_count > 4
| project UserPrincipalName, event_count, StartTime, EndTime, IPs, Apps
MFA fraud - If a user reports MFA fraud via authenticator app\phone then it's possible that the user has received an MFA challenge that they did not initiate. This could be a sign that the user's password has been compromised and a MFA fatigue attack is underway. The following KQL example will return users that have either denied MFA or reported fraud.
SigninLogs
| where TimeGenerated > ago (24hrs)
| where Status contains "MFA denied" or Status contains "Fraud"
| summarize by UserPrincipalName, tostring (Status.additionalDetails)
Count fraud
SigninLogs
| where Status contains "MFA denied" or Status contains "Fraud"
| summarize Count = count() by UserPrincipalName, tostring(Status.additionalDetails)
Account locked out - If a user's account has been locked out (smart lock out) it could indicate that sign-in attempts have come from a known malicious IP address, or the account was locked due to repeated sign-in attempts. The following KQL example will return users that have had their account locked out.
SigninLogs
| where TimeGenerated > ago (24hrs)
| where ResultType == "50053"
| summarize count() by UserPrincipalName
Users successfully authenticating to external Entra ID tenants - If your organization doesn't allow (or tightly controls) access to external Entra ID tenants then you can monitor this. This KQL example shows the user and tenantID of the resource tenant they accessed.
SigninLogs
| where TimeGenerated > ago (24hrs)
| where AADTenantId != ResourceTenantId
| where ResultType == "0"
| summarize count() by UserPrincipalName, ResourceTenantId
Users that have put in the correct passwords but failed the MFA and are risky users
SigninLogs
| where TimeGenerated >= ago(7d)
| where AuthenticationDetails contains '"Correct password' and Status contains "Failure" and RiskState == "atRisk"
| project
TimeGenerated,
Identity,
Location,
AuthenticationDetails,
AuthenticationRequirement,
Status,
RiskEventTypes,
RiskEventTypes_V2,
RiskLevelAggregated,
RiskLevelDuringSignIn,
RiskState,
ConditionalAccessStatus,
OperationName,
ResultType,
ResultDescription,
ClientAppUsed,
ConditionalAccessPolicies,
DeviceDetail,
Id,
IPAddress,
LocationDetails,
AppDisplayName,
ResourceDisplayName,
UserAgent
// Set v_Users_UPN with the UPN of the user of interest
let v_Users_UPN = "osotnoc@contoso.com"; // email goes here
SigninLogs
| where UserPrincipalName == v_Users_UPN
| summarize Count=count() by ResourceDisplayName, AppDisplayName
User count per Resource
How many Users have connected to a resource like AD an exchange
The query list the main reasons for sign in failures.
SigninLogs
| where ResultType != 0
| summarize Count=count() by ResultDescription, ResultType
| sort by Count desc nulls last
Failed login Count
Resources with most failed log in attempts.
SigninLogs
| where ResultType !=0
| summarize FailedLoginCount=count() by ResourceDisplayName
| sort by FailedLoginCount desc nulls last
Sign-in Locations
Failed and successful sign-ins by source location.
SigninLogs
| summarize Successful=countif(ResultType==0), Failed=countif(ResultType!=0) by Location
country
SigninLogs
| summarize
LastSeen = max(TimeGenerated),
SignInCount = count(),
Locations = make_set(Location)
by UserPrincipalName
| where LastSeen >= ago(3d)
| order by LastSeen desc
Sign-ins from Unfamiliar Countries
SigninLogs
| where Location !contains "US" // Replace with your expected country
| summarize Count = count(), LastSignIn = max(TimeGenerated) by UserPrincipalName, tostring(Location)
| order by Count desc