如何用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
相关产品推荐
相关产品推荐

