如何在PowerShell中不使用PAT完成Azure DevOps API调用的身份认证
不使用PAT调用Azure DevOps Web API的可行实现方案
完全可以直接通过调用认证接口获取访问令牌,无需依赖Azure CLI,也不需要手动生成PAT,常用有两种落地路径:
路径1:交互式用户认证(适合本地运行脚本场景)
使用Azure AD设备码授权流获取访问令牌,全程不需要硬编码密钥,只需要用户在浏览器完成身份校验即可,令牌权限和登录用户完全一致,无权限溢出风险。
- 首先在Azure AD中注册一个单租户应用,权限配置勾选Azure DevOps > user_impersonation委托权限,无需配置客户端密钥、重定向URI。
- 直接在PowerShell中调用认证接口拿令牌,参考代码如下:
# 替换为你的Azure AD租户ID、应用注册的客户端ID、Azure DevOps组织名称 $tenantId = "你的AAD租户ID" $clientId = "你注册的应用客户端ID" $devOpsOrg = "你的Azure DevOps组织名称" # 请求设备码 $deviceCodeResp = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/devicecode" -Body @{ client_id = $clientId scope = "499b84ac-1321-427f-aa17-267ca6975798/user_impersonation" } Write-Host $deviceCodeResp.message # 等待用户完成认证后轮询获取令牌 do { Start-Sleep -Seconds $deviceCodeResp.interval try { $tokenResp = Invoke-RestMethod -Method Post -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Body @{ grant_type = "urn:ietf:params:oauth:grant-type:device_code" client_id = $clientId device_code = $deviceCodeResp.device_code } -ErrorAction Stop break } catch { if ($_.Exception.Response.StatusCode -ne 400) { throw } } } while ($true) # 拿到令牌后直接调用Azure DevOps Web API即可,示例查询组织下的存储库列表 $apiHeaders = @{ Authorization = "Bearer $($tokenResp.access_token)" "Content-Type" = "application/json" } $repoList = Invoke-RestMethod -Method Get -Uri "https://dev.azure.com/$devOpsOrg/_apis/git/repositories?api-version=7.1-preview.1" -Headers $apiHeaders
路径2:非交互式托管标识认证(适合Azure环境内运行的脚本场景)
如果你的PowerShell脚本在Azure资源上运行(比如Azure VM、Azure Function、Azure Automation账户),可以直接给对应资源启用系统分配或用户分配托管标识,给托管标识授予Azure DevOps的对应权限后,直接从实例元数据服务拿令牌,全程不需要任何凭证硬编码。
参考代码如下:
# 替换为你的Azure DevOps组织名称、项目名称、流水线ID $devOpsOrg = "你的Azure DevOps组织名称" $projectName = "你的项目名称" $pipelineId = "目标流水线ID" # 从Azure实例元数据服务获取托管标识令牌 $tokenResp = Invoke-RestMethod -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=499b84ac-1321-427f-aa17-267ca6975798" -Headers @{Metadata = "true"} -Method Get # 调用DevOps API逻辑和路径1一致,示例触发流水线运行 $apiHeaders = @{ Authorization = "Bearer $($tokenResp.access_token)" "Content-Type" = "application/json" } $pipelineRunBody = @{ resources = @{ repositories = @{ self = @{} } } } | ConvertTo-Json -Depth 10 Invoke-RestMethod -Method Post -Uri "https://dev.azure.com/$devOpsOrg/$projectName/_apis/pipelines/$pipelineId/runs?api-version=7.1-preview.1" -Headers $apiHeaders -Body $pipelineRunBody
内容的提问来源于stack exchange,提问作者Rodge
相关产品推荐
相关产品推荐

