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

如何用PowerShell实现Remove-MgApplicationKey删除过期应用注册证书?

使用Microsoft Graph PowerShell模块删除过期应用注册证书

要完成删除过期应用注册证书的操作,核心是生成符合要求的Proof令牌——这是用来证明你拥有应用有效密钥所有权的JWT令牌,下面是完整的PowerShell实现方案:

一、生成Proof令牌的函数实现

根据要求,Proof令牌需要用应用的一个未过期有效密钥(证书)签名生成JWT,以下是封装好的PowerShell函数:

function New-MgApplicationProofToken {
    param(
        [Parameter(Mandatory=$true)]
        [string]$ApplicationId,
        [Parameter(Mandatory=$true)]
        [System.Security.Cryptography.X509Certificates.X509Certificate2]$SigningCertificate
    )

    # 构造JWT头部,指定签名算法和证书指纹
    $header = @{
        alg = "RS256"
        typ = "JWT"
        x5t = [Convert]::ToBase64String($SigningCertificate.GetCertHash()) -replace '\+', '-' -replace '/', '_' -replace '='
    } | ConvertTo-Json -Compress

    # 构造JWT负载,符合Graph要求的字段
    $currentUnixTime = [DateTimeOffset]::Now.ToUnixTimeSeconds()
    $payload = @{
        aud = "https://graph.microsoft.com"  # 受众为Graph API
        iss = $ApplicationId                 # 签发者为应用ID
        sub = $ApplicationId                 # 主体为应用ID
        exp = $currentUnixTime + 300         # 令牌有效期5分钟
        nbf = $currentUnixTime               # 生效时间为当前时间
        jti = [Guid]::NewGuid().ToString()   # 唯一标识
    } | ConvertTo-Json -Compress

    # 对头部和负载进行Base64Url编码
    $encodedHeader = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($header)) -replace '\+', '-' -replace '/', '_' -replace '='
    $encodedPayload = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($payload)) -replace '\+', '-' -replace '/', '_' -replace '='

    # 拼接待签名的内容
    $contentToSign = "$encodedHeader.$encodedPayload"

    # 使用证书私钥进行签名
    $privateKey = $SigningCertificate.PrivateKey
    if ($privateKey -is [System.Security.Cryptography.RSACryptoServiceProvider]) {
        $privateKey = [System.Security.Cryptography.RSA]$privateKey
    }
    $signatureBytes = $privateKey.SignData(
        [System.Text.Encoding]::UTF8.GetBytes($contentToSign),
        [System.Security.Cryptography.HashAlgorithmName]::SHA256,
        [System.Security.Cryptography.RSASignaturePadding]::Pkcs1
    )
    $encodedSignature = [Convert]::ToBase64String($signatureBytes) -replace '\+', '-' -replace '/', '_' -replace '='

    # 返回完整的JWT令牌作为Proof
    return "$encodedHeader.$encodedPayload.$encodedSignature"
}

二、完整操作流程

1. 准备依赖资源

  • 获取目标应用的ApplicationId(应用注册的客户端ID)
  • 加载该应用对应的一个未过期的证书(可以从本地证书存储获取,或者导出应用注册的证书到本地)

示例:从当前用户证书存储加载指定指纹的证书

# 替换为你的证书指纹
$certThumbprint = "ABC123DEF456GHI789JKL012MNO345PQR678STU90"
$signingCert = Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object { $_.Thumbprint -eq $certThumbprint }

# 替换为你的应用注册ID
$applicationId = "00000000-0000-0000-0000-000000000000"

2. 生成Proof令牌

$proofToken = New-MgApplicationProofToken -ApplicationId $applicationId -SigningCertificate $signingCert

3. 筛选并删除过期密钥

# 获取应用的所有密钥信息
$targetApp = Get-MgApplication -ApplicationId $applicationId -Select "PasswordCredentials"

# 筛选出已过期的密钥
$expiredKeys = $targetApp.PasswordCredentials | Where-Object { $_.EndDateTime -lt [DateTimeOffset]::Now }

# 批量删除过期密钥
foreach ($key in $expiredKeys) {
    $removeParams = @{
        KeyId = $key.KeyId
        Proof = $proofToken
    }
    Remove-MgApplicationKey -ApplicationId $applicationId -BodyParameter $removeParams
    Write-Host "已成功删除过期密钥:$($key.KeyId)"
}

三、关键注意事项

  • 用来签名的证书必须是目标应用注册中已存在的未过期有效密钥,否则生成的Proof令牌会被Graph API拒绝
  • 确保你的Microsoft Graph PowerShell会话拥有足够权限:Application.ReadWrite.All 或 Application.ReadWrite.OwnedBy
  • JWT令牌有效期建议设置为5分钟(如示例中的300秒),避免令牌泄露带来的风险
  • 如果应用使用的是对称密钥而非证书,需将签名算法改为HS256,但应用注册的密钥通常推荐使用证书类型的非对称密钥

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 05:25:24