使用PowerShell 5.1调用Invoke-RestMethod更新Azure DevOps变量组变量遇阻
Azure DevOps变量组PUT更新失败问题解决
环境
- PowerShell 5.1
- Azure DevOps Server 2020
问题描述
使用PowerShell 5.1的Invoke-RestMethod操作Azure DevOps库变量组:
- GET请求可正常获取变量组内容;
- 执行PUT请求时,最初无报错但变量未更新,仅返回类似GET请求的结果;后续触发Content-Type不支持错误,提示PUT方法仅接受
application/json或application/json-patch+json类型。
错误信息
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"The request indicated a Content-Type of \"\" for method type \"PUT\" which is not supported. Valid content types for this method are: application/json, application/json-patch+json.","typeName":"Microsoft.VisualStudio.Services.WebApi.VssRequestContentTypeNotSupportedException, Microsoft.VisualStudio.Services.WebApi","typeKey":"VssRequestContentTypeNotSupportedException","errorCode":0,"eventId":3000} At C:\Users\user1\Documents\WIP Update Password Library Group Variables.ps1:19 char:16 + ... $results = Invoke-RestMethod -Uri $uri -Credential $credential -Body ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
原代码
function Main{ SetVariable } function GetVariables { $uri = 'my azure devops uri' $credential = SetCredentials -userId 'user1' -password 'P@$$w0rd123' $results = Invoke-RestMethod -Uri $uri -Credential $credential $results.value.variables } function SetVariable { $uri = 'my azure devops uri' $credential = SetCredentials -userId 'user1' -password 'P@$$w0rd123' $body = @{ aVariableInGroup = 'hello world'} $results = Invoke-RestMethod -Uri $uri -Credential $credential -Body $body -Method Put $results } function SetCredentials ($userId, $password) { $securePassword = ConvertTo-SecureString -String $password -AsPlainText -Force return New-Object -TypeName PSCredential -ArgumentList $userId, $securePassword } Main
解决方法
问题根源
- 未指定Content-Type:原PUT请求未设置
-ContentType参数,导致请求头Content-Type为空,不符合Azure DevOps API要求; - 请求体格式错误:Azure DevOps变量组的PUT API需要提交完整的变量组对象,而非单个键值对;若仅需更新单个变量,使用PATCH方法更高效。
方案1:使用PUT方法(完整更新变量组)
先获取当前变量组的完整数据,修改目标变量后再提交PUT请求:
function SetVariable { # 确保URI指向具体变量组,格式示例:http://server:8080/tfs/Collection/Project/_apis/distributedtask/variablegroups/{groupId}?api-version=6.0 $uri = 'my azure devops uri' $credential = SetCredentials -userId 'user1' -password 'P@$$w0rd123' # 获取当前变量组完整数据 $currentVarGroup = Invoke-RestMethod -Uri $uri -Credential $credential # 修改目标变量的值 $currentVarGroup.variables.aVariableInGroup.value = 'hello world' # 转换为JSON字符串(需指定-Depth避免嵌套截断) $body = $currentVarGroup | ConvertTo-Json -Depth 10 # 发送PUT请求,指定Content-Type为application/json $results = Invoke-RestMethod -Uri $uri -Credential $credential -Body $body -Method Put -ContentType 'application/json' $results }
方案2:使用PATCH方法(部分更新变量)
通过JSON Patch格式仅提交需要修改的变量,更高效:
function SetVariable { $uri = 'my azure devops uri' $credential = SetCredentials -userId 'user1' -password 'P@$$w0rd123' # 构造JSON Patch请求体,指定替换操作 $patchBody = @( @{ op = 'replace' path = '/variables/aVariableInGroup/value' value = 'hello world' } ) | ConvertTo-Json -Depth 10 # 发送PATCH请求,指定Content-Type为application/json-patch+json $results = Invoke-RestMethod -Uri $uri -Credential $credential -Body $patchBody -Method Patch -ContentType 'application/json-patch+json' $results }
内容的提问来源于stack exchange,提问作者Rod
相关产品推荐
相关产品推荐

