使用PowerShell脚本递增DevOps变量组值时遇TF400898错误
问题描述
在使用PowerShell脚本获取、递增并更新Azure DevOps变量组中变量值时,触发TF400898内部错误,推测是递增后的值$versionNumber写入JSON字符串的方式错误导致的。
脚本代码:
# Base64-encodes the Personal Access Token (PAT) appropriately $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "","$env:SYSTEM_ACCESSTOKEN"))) $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/distributedtask/variablegroups/1?api-version=6.0-preview.1" $pipeline = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "Get Variable Value:" $pipeline.variables.MinorVersion.value $versionNumber = [int]$pipeline.variables.MinorVersion.value $versionNumber++ Write-Host "$versionNumber Variable Value:" $versionNumber $json = '{"id":2555,"type":"Vsts","name":"VersionNumberVG","variables":{"MinorVersion":{"value":$versionNumber}}}' $pipeline = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "PUT New Variable Value:" $pipeline.variables.MinorVersion.value $pipeline = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "Get Variable Value:" $pipeline.variables.MinorVersion.value
错误信息:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"TF400898: An Internal Error Occurred. Activity Id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx.","typeName":"Newtonsoft.Json.JsonReaderException, Newtonsoft.Json","typeKey":"JsonReaderException","errorCode":0,"eventId":0} At line:13 char:13 + $pipeline = Invoke-RestMethod -Uri $url -Method Put -Body $json -Cont ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
解决方案
核心问题是单引号包裹的字符串中PowerShell不会解析变量,导致发送的JSON里是$versionNumber字符串而非实际数值,触发JSON解析错误。以下是两种修复方式:
方法1:双引号拼接并转义内部引号
将JSON字符串改为双引号包裹,同时对内部的双引号用反引号`转义,让PowerShell正确解析变量:
$json = "{`"id`":2555,`"type`":`"Vsts`",`"name`":`"VersionNumberVG`",`"variables`":{`"MinorVersion`":{`"value`":$versionNumber}}}"
方法2:构建PS对象再转JSON(推荐)
手动拼接JSON容易出错,更可靠的方式是先创建PowerShell自定义对象,再用ConvertTo-Json生成标准JSON:
$variableGroup = [PSCustomObject]@{ id = 2555 type = "Vsts" name = "VersionNumberVG" variables = [PSCustomObject]@{ MinorVersion = [PSCustomObject]@{ value = $versionNumber } } } $json = $variableGroup | ConvertTo-Json -Depth 3
额外注意事项
- 确保JSON中的
id字段和URL里的变量组ID一致(你的URL中是1,但JSON写的2555,需检查匹配) - 使用
ConvertTo-Json时要指定足够的-Depth参数,避免嵌套对象被截断
修改后的完整脚本
# Base64-encodes the Personal Access Token (PAT) appropriately $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "","$env:SYSTEM_ACCESSTOKEN"))) $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/distributedtask/variablegroups/1?api-version=6.0-preview.1" $pipeline = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "Get Variable Value:" $pipeline.variables.MinorVersion.value $versionNumber = [int]$pipeline.variables.MinorVersion.value $versionNumber++ Write-Host "Updated Variable Value:" $versionNumber # 构建对象并转换为标准JSON $variableGroup = [PSCustomObject]@{ id = 1 # 与URL中的变量组ID保持一致 type = "Vsts" name = "VersionNumberVG" variables = [PSCustomObject]@{ MinorVersion = [PSCustomObject]@{ value = $versionNumber } } } $json = $variableGroup | ConvertTo-Json -Depth 3 $pipeline = Invoke-RestMethod -Uri $url -Method Put -Body $json -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "PUT New Variable Value:" $pipeline.variables.MinorVersion.value $pipeline = Invoke-RestMethod -Uri $url -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} Write-Host "Get Variable Value:" $pipeline.variables.MinorVersion.value
内容的提问来源于stack exchange,提问作者CompileNow
相关产品推荐
相关产品推荐

