You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PowerShell通过证书替代密钥连接Microsoft Graph获取Azure AD用户最后登录信息

用证书无交互连接Microsoft Graph并提取用户最后登录信息

一、准备证书

生产环境建议使用企业CA颁发的证书,测试场景可自签证书:

# 生成自签证书,私钥存储在当前用户证书库
New-SelfSignedCertificate -Subject "CN=GraphAuthCert" -CertStoreLocation "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 -KeyAlgorithm RSA -HashAlgorithm SHA256

执行后导出证书的公钥(.cer格式),私钥保留在服务器的证书存储中,确保只有脚本运行账户有权限访问。

二、配置Azure AD应用注册

  1. 登录Azure门户,进入应用注册,选中目标应用(或新建应用)。
  2. 在证书和密码页面,点击上传证书,选择刚才导出的.cer文件,完成后保存。
  3. 切换到API权限页面,点击添加权限 → 选择Microsoft Graph → 应用权限:
    • 添加User.Read.All(读取用户基础信息)
    • 添加AuditLog.Read.All(读取登录日志,用于获取精准登录记录)
  4. 点击授予管理员同意,完成权限配置。

三、无交互连接Graph并提取用户最后登录信息

方式1:直接从用户对象获取LastSignInDateTime

适合快速获取用户最后登录时间:

# 配置参数
$tenantId = "你的租户ID"
$clientId = "应用注册的客户端ID"
$certThumbprint = "证书的指纹(可从证书属性中复制)"

# 安装/更新Microsoft Graph模块(首次运行需执行)
Install-Module Microsoft.Graph -Force -AllowClobber

# 无交互连接Graph
Connect-MgGraph -TenantId $tenantId -ClientId $clientId -CertificateThumbprint $certThumbprint

# 获取用户及最后登录时间
$userLoginData = Get-MgUser -All -Property Id, DisplayName, UserPrincipalName, LastSignInDateTime | 
    Select-Object DisplayName, UserPrincipalName, LastSignInDateTime | 
    Sort-Object LastSignInDateTime -Descending

# 输出结果
$userLoginData

方式2:从登录日志获取精准登录记录(含更多细节)

如果需要登录状态、客户端IP等额外信息,可查询审计日志:

# 配置参数
$tenantId = "你的租户ID"
$clientId = "应用注册的客户端ID"
$certThumbprint = "证书的指纹"

# 连接Graph
Connect-MgGraph -TenantId $tenantId -ClientId $clientId -CertificateThumbprint $certThumbprint

# 获取最近30天的登录记录,按用户分组取最后一次
$latestSignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge (now()-duration'30.00:00:00')" -All | 
    Group-Object UserId | 
    ForEach-Object {
        $_.Group | Sort-Object CreatedDateTime -Descending | Select-Object -First 1
    }

# 关联用户信息并输出
$latestSignIns | ForEach-Object {
    $user = Get-MgUser -UserId $_.UserId -Property DisplayName, UserPrincipalName
    [PSCustomObject]@{
        DisplayName       = $user.DisplayName
        UserPrincipalName = $user.UserPrincipalName
        LastSignInTime    = $_.CreatedDateTime
        SignInStatus      = if ($_.Status.ErrorCode -eq 0) { "成功" } else { "失败(错误码:$($_.Status.ErrorCode))" }
        ClientIP          = $_.ClientIpAddress
    }
} | Sort-Object LastSignInTime -Descending

注意事项

  • 服务器上的证书私钥权限必须严格限制,仅允许运行脚本的服务账户访问,避免泄露。
  • 应用权限遵循最小权限原则,仅分配必要权限。
  • 生产环境请使用CA颁发的证书,避免自签证书带来的信任风险。

内容的提问来源于stack exchange,提问作者Kalana D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:34:53