使用PowerShell调用Azure DevOps REST API发布构建制品遇JSON错误求助
问题:PowerShell调用Azure DevOps构建制品API报错JsonReaderException
问题场景
尝试通过PowerShell调用Azure DevOps构建制品创建API,将文件发布为构建管道制品,原代码如下:
$url = "https://dev.azure.com/<org>/<project>/_apis/build/builds/<buildId>/artifacts?api-version=7.2-preview.5" $body = @{ name = 'testpublish' resource = @{ data = "./testfolder/*" type = "filepath" } } $headers = @{ 'Authorization' = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":<pat>")) 'Content-Type' = 'application/json' } $response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $body
错误信息
执行后抛出JSON解析错误:
Invoke-RestMethod: { "$id": "1", "innerException": null, "message": "TF400898: An Internal Error Occurred.", "typeName": "Newtonsoft.Json.JsonReaderException, Newtonsoft.Json", "typeKey": "JsonReaderException", "errorCode": 0, "eventId": 0 }
解决方案
1. 修复JSON序列化问题
错误核心原因:PowerShell直接传入哈希表$body时,Invoke-RestMethod会默认将其转换为表单数据,而非JSON格式,导致API无法解析请求体。需要将哈希表转为JSON字符串:
# 修正后的请求体处理 $jsonBody = $body | ConvertTo-Json -Depth 10 $response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $jsonBody
- 注意添加
-Depth 10:避免嵌套对象(如resource)因默认深度限制被截断。
2. 修正资源路径参数
resource.data字段并非本地文件路径,该API仅针对Azure DevOps构建代理上下文运行:
- 若在构建管道的PowerShell任务中执行,需使用代理上的绝对路径,例如:
resource = @{ data = "$(Build.ArtifactStagingDirectory)/testfolder/*" type = "filepath" } - 若想从本地机器直接上传文件到Azure DevOps制品,该API不适用,建议改用Azure CLI命令
az artifacts universal publish,或Azure DevOps通用制品库的上传REST API。
3. 验证PAT权限
确保你的个人访问令牌(PAT)拥有以下权限:
- 范围选择
Build(勾选Read & Execute) - 或更精细的
Artifacts(勾选Write)
修正后的完整代码(构建管道内使用)
$org = "你的组织名" $project = "你的项目名" $buildId = "目标构建ID" $pat = "你的PAT令牌" $url = "https://dev.azure.com/$org/$project/_apis/build/builds/$buildId/artifacts?api-version=7.2-preview.5" $body = @{ name = 'testpublish' resource = @{ data = "$(Build.ArtifactStagingDirectory)/testfolder/*" type = "filepath" } } $headers = @{ 'Authorization' = "Basic " + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$pat")) 'Content-Type' = 'application/json' } $jsonBody = $body | ConvertTo-Json -Depth 10 $response = Invoke-RestMethod -Uri $url -Method Post -Headers $headers -Body $jsonBody
内容的提问来源于stack exchange,提问作者lbpoundz
相关产品推荐
相关产品推荐

