Tenant variables put operation failing with 400 response code


I am trying to update tenant variables for a project for an environment.
My PowerShell code which I took from here “Update tenant variables - Octopus Deploy” is failing with “InvalidOperation: The remote server returned an error: (400) Bad Request” and Sometime 500 error.
Same updated Json body is working fine with postman.

Please help me here.

Hi @vipinkumar,

Thanks for reaching out.

What are the differences in the script parameters when you’re getting a 400 vs a 500?

The 500 error should be in the Octopus Server log. Can you please take a look at the OctopusServer log and let me know what it is? You can attach the entire log if you prefer. The default location is on the server hosting Octopus in C:\Octopus\Logs.

Please feel free to DM me anything private.


Hi Jeremy,

I don’t have access to Octopus server so can’t see the logs. Now I am getting “The remote server returned an error: (400) Bad Request”. The same updated json I am using in postman with same api key and working fine. I am using Octopus deploy version 2021.3 (Build 12372). Below is the code which I am using.

$ErrorActionPreference = “Stop”;

$octopusURL = “https://”
$octopusAPIKey = “API-”

$header = @{ “X-Octopus-ApiKey” = $octopusAPIKey }

$spaceName = “Default” # Name of the Space
$tenantName = “GEN1” # The tenant name
$variableTemplateName = “JobFrequency” # Choose the template Name
$newValue = “1” # Choose a new variable value, assumes same per environment
$NewValueIsBoundToOctopusVariable = $False # Choose $True if the $newValue is an Octopus variable e.g. #{SomeValue}

$space = (Invoke-RestMethod -Method Get -Uri “$octopusURL/api/spaces/all” -Headers $header) | Where-Object { $_.Name -eq $spaceName }

$tenantsSearch = (Invoke-RestMethod -Method Get -Uri “$octopusURL/api/$($space.Id)/tenants?name=$tenantName” -Headers $header)
$tenant = $tenantsSearch.Items | Select-Object -First 1

$variables = (Invoke-RestMethod -Method Get -Uri “$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables” -Headers $header)

$projects = $variables.ProjectVariables | Get-Member | Where-Object { $_.MemberType -eq “NoteProperty” } | Select-Object -ExpandProperty “Name”

foreach ($projectKey in $projects) {
if (“Projects-123” -eq $projectKey) {
# Get connected project
$project = $variables.ProjectVariables.$projectKey
$projectName = $project.ProjectName
Write-Host “Working on Project: $projectName ($projectKey)”

    $variableTemplate = ($project.Templates | Where-Object Name -eq $variableTemplateName | Select-Object -First 1)

    if ($null -ne $variableTemplate) {

        $variableTemplateId = $variableTemplate.Id
        $variableTemplateIsSensitiveControlType = $variableTemplate.DisplaySettings["Octopus.ControlType"] -eq "Sensitive"

        Write-Host "Found templateId for Template: $variableTemplateName = $variableTemplateId"
        $projectConnectedEnvironments = $project.Variables | Get-Member | Where-Object { $_.MemberType -eq "NoteProperty" } | Select-Object -ExpandProperty "Name"

        # Loop through each of the connected environments variables
        foreach ($envKey in $projectConnectedEnvironments) {
            if ($envKey -eq "Environments-16") {
                # Check for Environment project template entry, and add if not present
                if ($null -eq $project.Variables.$envKey.$variableTemplateId) {
                    $project.Variables.$envKey | Add-Member -MemberType NoteProperty -Name $variableTemplateId -Value $newValue

                # Check sensitive control types differently
                if ($variableTemplateIsSensitiveControlType -eq $True) {
                    # If $newValue denotes an octopus variable e.g. #{SomeVar}, treat it as if it were text
                    if ($NewValueIsBoundToOctopusVariable -eq $True) {      
                        Write-Host "Adding in new text value (treating as octopus variable) in Environment '$envKey' for $variableTemplateName"             
                        $project.Variables.$envKey.$variableTemplateId = $newValue
                    else {
                        $newSensitiveValue = [PsCustomObject]@{
                            HasValue = $True
                            NewValue = $newValue
                        Write-Host "Adding in new sensitive value = '********' in Environment '$envKey' for $variableTemplateName"
                        $project.Variables.$envKey.$variableTemplateId = $newSensitiveValue
                else {
                    Write-Host "Adding in new value = $newValue in Environment '$envKey' for $variableTemplateName"
                    $project.Variables.$envKey.$variableTemplateId = $newValue
    else {
        Write-Host "Couldnt find project template: $variableTemplateName for project $projectName"


$variablesOld = (Invoke-RestMethod -Method Get -Uri “$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables” -Headers $header)
$vold = (($variablesOld | convertto-json -Depth 10) -split ‘\r?\n’)
$vnew = (($variables | convertto-json -Depth 10) -split ‘\r?\n’)

Write-Host “-- – – – Below is json comparison details”
(Compare-Object -ReferenceObject $vold -DifferenceObject $vnew) | Format-Table -Wrap

Invoke-RestMethod -Method Put -Uri “$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables” -Headers $header -Body ($variables | convertto-json -Depth 10) -ContentType application/json

Sorry for the delay @vipinkumar,

I’m still looking into this, however haven’t had much luck triggering a 400 error.

Do you have more details, i.e. the line in which the 400 error is triggered?
What exactly do you change in order to get a 500 error instead of a 400 error or is it intermittent with no changes to the script necessary?

Do you get any output when you run the script? i.e. does the lines “Working on Project: $projectName ($projectKey)” get printed?

Do the values look correct? i.e. does it print out “Projects-123”


Hi Dane,

I am getting error at line with PUT operation “Invoke-RestMethod -Method Put -Uri “$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables” -Headers $header -Body ($variables | convertto-json -Depth 10) -ContentType application/json”

Now error code is 400 only. Yes, projects keys are getting printed.

Output is like “Working on Project: Test-Project (Projects-123)”

Hi @vipinkumar,

Everything seems to be working correctly from my end. The only changes I had to make from your script was the ID’s of the various targets (Projects, Environments, etc) and some character formatting issues - which I am confident was caused by Discourse itself, when you were pasting it in to the ticket.

I’m a bit stuck on what the issue might be.

Can you confirm your SSL certificate for your Octopus server is current, has no errors and is trusted?

I’m not sure if you’ve DM’d the Server Logs to Jeremy - however this might be a batter location to upload your logs - so that it’s accessible to the Octopus Staff.

Also, just for some more context, what is the variableTemplate control type? I’ve been testing so far with a non sensitive single line variable.


Hi Dane,

I tried with python code from “Update tenant variables - Octopus Deploy” and that is working fine. So might be issue with my PowerShell only. Thanks for your support. This can be closed.


1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.