为何我的PowerShell代码无法获取全部Azure用户的最后登录时间?
问题排查:PowerShell获取Azure AD用户最后登录时间空白问题
问题现象
执行以下PowerShell代码后,沙盒Azure环境中多数虚拟用户显示No sign-ins found(符合预期),但3个真实账户的LastSignInDate字段显示空白。尝试移除if ($userSignIns.Count -gt 0)语句后仍未解决问题。
原代码
# Connect to Azure AD (if not connected) Connect-AzAccount # Construct the URI for user sign-ins $uri = "https://graph.microsoft.com/v1.0/auditLogs/signIns" # Create an array to store the results $results = @() try { # Make the API call to retrieve all sign-ins $response = Invoke-RestMethod -Uri $uri -Method Get -Headers @{ Authorization = "Bearer $((Get-AzAccessToken -ResourceUrl https://graph.microsoft.com).Token)" } Write-Host $response # Process the response and extract last sign-in date for each user foreach ($user in $allUsers) { $userSignIn = $user.UserPrincipalName # Filter the response to get sign-ins for the current user $userSignIns = $response.value | Where-Object { $_.userPrincipalName -eq $userSignIn } if ($userSignIns.Count -gt 0) { # Sort sign-ins by activity date and extract the latest one $lastSignInDate = $_.SignInActivity.LastSignInDateTime } else { $lastSignInDate = 'No sign-ins found' } # Construct the result object $result = [PSCustomObject]@{ 'User' = $userSignIn 'LastSignInDate' = $lastSignInDate } $results += $result } } catch { Write-Host "Error retrieving sign-ins: $_" } # Export the results to a CSV file $results | Export-Csv -Path 'OutputLocation\PowershellOutput.csv' -NoTypeInformation
问题分析与修复
核心问题点
- 未定义
$allUsers变量:原代码直接循环$allUsers但未添加获取Azure AD用户列表的逻辑,真实用户的遍历基础缺失。 - 错误使用管道变量
$_:if块中的$_.SignInActivity.LastSignInDateTime里的$_并非指向过滤后的用户登录记录,此时$_为空,导致字段空白。 - 单条结果时
Count判断失效:当$userSignIns只有1条结果时,PowerShell不会将其视为数组,Count属性为空,导致判断逻辑错误。 - Graph API分页未处理:默认
auditLogs/signIns接口仅返回最近100条记录,真实用户的登录记录可能不在初始结果中。
修复后的代码
# Connect to Azure AD (if not connected) Connect-AzAccount # 获取所有Azure AD用户 $allUsers = Get-AzADUser -All $true # 初始化变量存储所有登录记录 $uri = "https://graph.microsoft.com/v1.0/auditLogs/signIns" $allSignIns = @() $results = @() try { # 处理Graph API分页,获取完整登录记录 do { $response = Invoke-RestMethod -Uri $uri -Method Get -Headers @{ Authorization = "Bearer $((Get-AzAccessToken -ResourceUrl https://graph.microsoft.com).Token)" } $allSignIns += $response.value $uri = $response.'@odata.nextLink' } while ($uri) # 遍历每个用户提取最后登录时间 foreach ($user in $allUsers) { $userUpn = $user.UserPrincipalName # 过滤当前用户的登录记录 $userSignIns = $allSignIns | Where-Object { $_.userPrincipalName -eq $userUpn } # 强制转为数组,避免单条记录时Count判断失效 if (@($userSignIns).Count -gt 0) { # 按登录时间降序排序,取第一条记录的时间 $lastSignInDate = ($userSignIns | Sort-Object -Property createdDateTime -Descending)[0].createdDateTime } else { $lastSignInDate = 'No sign-ins found' } # 构造结果对象并添加到数组 $results += [PSCustomObject]@{ 'User' = $userUpn 'LastSignInDate' = $lastSignInDate } } } catch { Write-Host "Error retrieving sign-ins: $_" } # 导出结果到CSV(添加UTF8编码避免乱码) $results | Export-Csv -Path 'OutputLocation\PowershellOutput.csv' -NoTypeInformation -Encoding UTF8
修复说明
- 补充
Get-AzADUser -All $true获取完整Azure AD用户列表; - 处理Graph API分页逻辑,确保获取全部登录记录;
- 用
@($userSignIns)强制转为数组,修正单条记录时的Count判断问题; - 对用户登录记录按
createdDateTime降序排序,取第一条作为最后登录时间; - 添加
-Encoding UTF8避免CSV导出时出现中文乱码。
内容的提问来源于stack exchange,提问作者Jon24601
相关产品推荐
相关产品推荐

