用于在 Azure 门户中查找过去 90 天内未登录的非活动用户的 KQL

KQL for finding inactive users in Azure Portal for who have not logged-in for last 90 days

出于安全原因,我们希望删除在 Azure 门户中超过 90 天不活动的用户。 我们已经设置了 azure 广告诊断设置推送数据到这个日志分析工作区。现在我们能够 运行 以下 KQL query.But 查询不准确,因为它在 90 天之前获取用户,但一些用户也在过去 90 天登录。

SigninLogs
|extend d =parse_json(AuthenticationDetails)
|where  todatetime(d[0].authenticationStepDateTime)  < ago(90d) 
and TimeGenerated  < ago(90d) and AppDisplayName == "Azure Portal" 
and OperationName =="Sign-in activity" and isnotempty(AlternateSignInName) 
|project Identity,Location,AlternateSignInName, authenticationStep= d[0].authenticationStepDateTime
|distinct  AlternateSignInName, Identity

更新: 我根据答案将查询更新为以下内容。但它从日志分析默认时间范围而不是查询时间范围中获取日期范围。知道如何修正这个时间范围吗?

let SigninUsersBeyond90Days = SigninLogs
| extend d = parse_json(AuthenticationDetails)
| extend LoginTimestamp = todatetime(d[0].authenticationStepDateTime)
| where AppDisplayName == "Azure Portal" and OperationName == "Sign-in activity" and isnotempty(AlternateSignInName) 
| summarize max(LoginTimestamp) by AlternateSignInName, Identity
| where max_LoginTimestamp > ago(90d)
| distinct AlternateSignInName;

SigninLogs
| extend d = parse_json(AuthenticationDetails)
| extend LoginTimestamp = todatetime(d[0].authenticationStepDateTime)
| where AppDisplayName == "Azure Portal" and OperationName == "Sign-in activity" and isnotempty(AlternateSignInName)  
and AlternateSignInName  !in(SigninUsersBeyond90Days)
| summarize max(LoginTimestamp) by AlternateSignInName, Identity
| where max_LoginTimestamp < ago(90d)
| distinct AlternateSignInName, Identity

更新了查询以拉取过去 90 天未在 Azure 门户中登录的用户,因为 below.This 还按照建议修复了我的上述日志分析过滤器问题。

let SigninUsersWithin90Days = SigninLogs
| extend d = parse_json(AuthenticationDetails)
| extend LoginTimestamp = todatetime(d[0].authenticationStepDateTime)
| where AppDisplayName == "Azure Portal" and OperationName == "Sign-in activity" and isnotempty(AlternateSignInName) 
| summarize max(LoginTimestamp) by AlternateSignInName, Identity
| where max_LoginTimestamp < ago(90d) 
| distinct AlternateSignInName;

SigninLogs
| extend d = parse_json(AuthenticationDetails)
| extend LoginTimestamp = todatetime(d[0].authenticationStepDateTime)
| where AppDisplayName == "Azure Portal" and OperationName == "Sign-in activity" and isnotempty(AlternateSignInName)  and TimeGenerated > ago(90d)
and AlternateSignInName  !in(SigninUsersWithin90Days)
| summarize max(LoginTimestamp) by AlternateSignInName, Identity
| where max_LoginTimestamp > ago(90d) 
| distinct AlternateSignInName, Identity

你需要使用max聚合函数,像这样:

SigninLogs
| extend d = parse_json(AuthenticationDetails)
| extend LoginTimestamp = todatetime(d[0].authenticationStepDateTime)
| where AppDisplayName == "Azure Portal" and OperationName == "Sign-in activity" and isnotempty(AlternateSignInName) 
| summarize max(LoginTimestamp) by AlternateSignInName, Identity
| where max_LoginTimestamp < ago(90d)
| distinct AlternateSignInName, Identity