Powershell Invoke-RestMethod from VSTS build step

2019-08-15 06:39发布

问题:

We bought ourselves a Lametric clock (www.lametric.com) which supports displaying messages sent to it through a Web-API. We would like to integrate this into our CI/CD queue. For that we have written a Powershell script, which will send a specified notification. This script works fine, when executed locally. When executed from a (local) VSTS Build Agent, it fails with a status code 417.

This is the powershell script:

Param (
    [Parameter(mandatory=$true)]
    [string] $BuildName,
    [Parameter(mandatory=$false)]
    [string] $Message
)


$Payload = '{"priority":"critical","icon_type":"alert","lifeTime":2000,"model":{"frames":[{"icon":"555","text":"' + $BuildName + ' BUILD FAILED! ' + $Message + '"}],"sound":{"category":"alarms","id":"alarm6","repeat":2},"cycles":0}}'

$request = @{uri = 'http://<ip-address>:8080/api/v2/device/notifications';
              Method = 'POST';
              Headers = @{Authorization = 'Basic <base64-encoded-credentials>='; "Content-Type" = 'application/json' }
       Body = $Payload
  }

invoke-restmethod @request

Can someone point us into the right direction, as to why we are experiencing this issue from the build step, but not locally?

Update 1:

If I strip out all variables it still failes.

Update 2:

  • Changing Invoke-RestMethod to Invoke-WebRequest does not make a differnce.
  • Invoking a GET request works
  • Invoking a POST request fails with error 417

回答1:

It seems I found a solution to the problem. Seeing that sending a GET request with the option -UseBasicParsing worked fine, I tried combining the two requests one after the other. This did not work, if they were in two separate build steps.

However once I sent a GET request and followed it up with the above mentioned POST request, it magically worked. I don't know, why this works, but here is our current solution:

Param (
        [Parameter(mandatory=$true)]
        [string] $BuildName,
        [Parameter(mandatory=$false)]
        [string] $Message
)

$request = @{uri = 'http://<ip-address>:8080/api/v2';
            Method = 'GET';
            Headers = @{Authorization = 'Basic <base64-encoded-credentials>'; }
  }

invoke-webrequest -UseBasicParsing @request

$Payload = '{"priority":"critical","icon_type":"alert","lifeTime":2000,"model":{"frames":[{"icon":"555","text":"' + $BuildName + ' BUILD FAILED! ' + $Message + '"}],"sound":{"category":"alarms","id":"alarm6","repeat":2},"cycles":0}}'

$request = @{uri = 'http://<ip-address>:8080/api/v2/device/notifications';
            Method = 'POST';
            Headers = @{Authorization = 'Basic <base64-encoded-credentials>'; "Content-Type" = 'application/json' }
            Body = $Payload
  }

invoke-webrequest -UseBasicParsing @request