PowerShell查询特定设备最后登录活动的问题求助
问题分析与解决建议
核心问题
你需要获取Azure门户「用户>设备」页面中「活动」列的设备登录时间,但使用Get-AzureADAuditSignInLogs的两种写法均无返回结果,同时脚本混合使用了Microsoft Graph PowerShell模块(Connect-MgGraph、Get-Mg* cmdlet)和AzureAD模块(Connect-AzureAD、Get-AzureADAuditSignInLogs),这可能导致权限或语法适配问题。
问题排查与修复步骤
1. 权限缺失
Get-AzureADAuditSignInLogs需要AuditLog.Read.All和Directory.Read.All权限,Connect-AzureAD默认不会请求这些权限。如果坚持使用AzureAD模块,需重新连接并指定权限:
Connect-AzureAD -Scopes "AuditLog.Read.All", "Directory.Read.All"
更建议统一使用Microsoft Graph PowerShell模块(你的脚本主要基于此),避免混合模块带来的兼容性问题。
2. 语法错误修正
你尝试的两种Get-AzureADAuditSignInLogs写法存在问题:
- 第一种:Filter路径错误,应为
DeviceDetail/DeviceId,且变量嵌入需注意引号解析:# 正确写法 $deviceResults = Get-AzureADAuditSignInLogs -Filter "DeviceDetail/DeviceId eq '$deviceID'" -Top 1 - 第二种:
Where-Object无法直接使用DeviceDetail/DeviceId作为属性路径,需用脚本块,且单引号包裹变量会导致变量不解析:# 正确写法 Get-AzureADAuditSignInLogs | Where-Object { $_.DeviceDetail.DeviceId -eq $deviceID }
3. 推荐方案:统一使用Microsoft Graph模块
既然脚本主要使用Get-Mg* cmdlet,建议用Get-MgAuditLogSignIn替代Get-AzureADAuditSignInLogs,语法更一致且权限管理更清晰:
# 获取设备最新登录时间 $latestSignIn = Get-MgAuditLogSignIn -Filter "DeviceDetail/DeviceId eq '$deviceId'" -Top 1 -Property CreatedDateTime $loginTime = if ($latestSignIn) { $latestSignIn.CreatedDateTime } else { "无登录记录" }
使用前确保Connect-MgGraph已请求正确权限:
Connect-MgGraph -NoWelcome -Scopes "AuditLog.Read.All", "Directory.Read.All", "User.Read.All"
4. 完整脚本优化建议
以下是整合登录时间查询的优化版脚本,同时修复了数组效率问题(避免用+=重建数组):
# 连接Microsoft Graph并请求必要权限 Connect-MgGraph -NoWelcome -Scopes "AuditLog.Read.All", "Directory.Read.All", "User.Read.All" # 导入CSV数据 $CSVData = Import-CSV -Path "C:\PSTest\Employees.csv" # 优化账户存在性检查函数,避免重复查询 function Test-AccountExists { param($UserN) $user = Get-MgUser -Filter "Displayname eq '$UserN'" -ErrorAction Ignore return [PSCustomObject]@{ Exists = [bool]$user UserObject = $user } } # 使用ArrayList提升数组操作效率 $resultsArr = New-Object System.Collections.ArrayList foreach ($row in $CSVData) { $fullname = "$($row.'First Name') $($row.'Last Name')" $empId = $row.'Employee Id' Write-Host "处理用户:$fullname (ID: $empId)" $accountCheck = Test-AccountExists -UserN $fullname if ($accountCheck.Exists) { $user = $accountCheck.UserObject Write-Host "找到用户:$($user.UserPrincipalName) (ID: $($user.Id))" $devices = Get-MgUserOwnedDevice -UserId $user.Id if ($devices) { foreach ($device in $devices) { $deviceDetails = Get-MgDevice -DeviceId $device.Id $deviceId = $device.Id # 查询设备最新登录时间 $latestSignIn = Get-MgAuditLogSignIn -Filter "DeviceDetail/DeviceId eq '$deviceId'" -Top 1 -Property CreatedDateTime $loginTime = if ($latestSignIn) { $latestSignIn.CreatedDateTime } else { "无登录记录" } # 检查合规状态 $complianceState = if ($deviceDetails.IsCompliant) { "Y" } else { "N" } $null = $resultsArr.Add([PSCustomObject]@{ 'Employee Id' = $empId 'Full Name' = $fullname 'User Principal Name' = $user.UserPrincipalName 'Device Name' = $deviceDetails.DisplayName 'Compliance State' = $complianceState 'Last Login Time' = $loginTime 'Azure Account' = "Yes" }) } } else { Write-Host "该用户无关联设备" $null = $resultsArr.Add([PSCustomObject]@{ 'Employee Id' = $empId 'Full Name' = $fullname 'User Principal Name' = $user.UserPrincipalName 'Device Name' = "No device in Azure" 'Compliance State' = "NA" 'Last Login Time' = "NA" 'Azure Account' = "Yes" }) } } else { Write-Host "未找到该用户" $null = $resultsArr.Add([PSCustomObject]@{ 'Employee Id' = $empId 'Full Name' = $fullname 'User Principal Name' = "NA" 'Device Name' = "NA" 'Compliance State' = "NA" 'Last Login Time' = "NA" 'Azure Account' = "No" }) } } # 导出结果到CSV $resultsArr | Export-Csv -Path "C:\pstest\Results.csv" -NoTypeInformation # 清理资源 $resultsArr.Clear() Disconnect-MgGraph
额外注意事项
- 登录日志默认保留30天,如果设备超过30天未登录,将无法查询到记录。
- 确保执行脚本的账号具有足够的Azure AD权限(全局管理员、安全管理员或审计管理员角色)。
- 避免在循环中频繁调用Graph API,可考虑批量查询提升效率(比如先收集所有设备ID,再批量查询登录日志)。
内容的提问来源于stack exchange,提问作者user765081
相关产品推荐
相关产品推荐

