Update tenant variables

These scripts demonstrate how to programmatically update tenant variables.

Update project tenant variables

Provide values for:

  • Octopus URL
  • Octopus API Key
  • Name of the space to use
  • Name of the tenant
  • Name of the Project template
  • The new variable value
  • Choose whether the new variable value is bound to an Octopus variable value e.g. #{MyVariable}
PowerShell (REST API)
$ErrorActionPreference = "Stop";

# Define working variables
$octopusURL = "https://your-octopus-url"
$octopusAPIKey = "API-YOUR-KEY"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

$spaceName = "Default" # Name of the space
$tenantName = "TenantName" # The tenant name
$projectVariableTemplateName = "ProjectTemplateName" # Choose the template name
$newValue = "NewValue" # Choose a new variable value, assumes same per environment
$NewValueIsBoundToOctopusVariable=$False # Choose $True if the $newValue is an Octopus variable e.g. #{SomeValue}

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

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

# Get Project Tenant Variables (including missing variables)
$projectVariablesUri = "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/projectvariables?includeMissingVariables=true"
$projectVariables = (Invoke-RestMethod -Method Get -Uri $projectVariablesUri -Headers $header)

# Build update payload
$updatePayload = @{
  Variables = @()
}

# Loop through project variables
foreach ($variable in $projectVariables.Variables) {
  if ($variable.Template.Name -eq $projectVariableTemplateName) {
    Write-Host "Found project variable template: $projectVariableTemplateName (Template ID: $($variable.Template.Id), Project ID: $($variable.ProjectId))"

    # Create new variable entry
    $variableEntry = @{
      ProjectId = $variable.ProjectId
      TemplateId = $variable.Template.Id
      Scope = @{
        EnvironmentIds = $variable.Scope.EnvironmentIds
      }
    }

    # Handle sensitive values
    if($variable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
      if($NewValueIsBoundToOctopusVariable -eq $True) {
        $variableEntry.Value = $newValue
      } else {
        $variableEntry.Value = @{
          HasValue = $true
          NewValue = $newValue
        }
      }
      Write-Host "Updated sensitive variable for environments: $($variable.Scope.EnvironmentIds -join ', ')"
    } else {
      $variableEntry.Value = $newValue
      Write-Host "Updated variable value to '$newValue' for environments: $($variable.Scope.EnvironmentIds -join ', ')"
    }

    $updatePayload.Variables += $variableEntry
  } else {
    # Keep existing variables unchanged
    $updatePayload.Variables += @{
      Id = $variable.Id
      ProjectId = $variable.ProjectId
      TemplateId = $variable.TemplateId
      Value = $variable.Value
      Scope = $variable.Scope
    }
  }
}

# Handle variables that need to be created
if ($projectVariables.MissingVariables) {
  foreach ($missingVariable in $projectVariables.MissingVariables) {
    if ($missingVariable.Template.Name -eq $projectVariableTemplateName) {
      Write-Host "Found missing project variable template: $projectVariableTemplateName (Template ID: $($missingVariable.Template.Id), Project ID: $($missingVariable.ProjectId))"

      # Create new variable entry for missing variable
      $variableEntry = @{
        ProjectId = $missingVariable.ProjectId
        TemplateId = $missingVariable.Template.Id
        Scope = @{
          EnvironmentIds = $missingVariable.Scope.EnvironmentIds
        }
      }

      # Handle sensitive values
      if($missingVariable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
        if($NewValueIsBoundToOctopusVariable -eq $True) {
          $variableEntry.Value = $newValue
        } else {
          $variableEntry.Value = @{
            HasValue = $true
            NewValue = $newValue
          }
        }
        Write-Host "Created sensitive variable for missing template"
      } else {
        $variableEntry.Value = $newValue
        Write-Host "Created variable value '$newValue' for missing template"
      }

      $updatePayload.Variables += $variableEntry
    }
  }
}

# Update project variables
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/projectvariables" -Headers $header -Body ($updatePayload | ConvertTo-Json -Depth 10)
Write-Host "Successfully updated project tenant variables"
PowerShell (Octopus.Client)
# You can get this dll from your Octopus Server/Tentacle installation directory or from
# https://www.nuget.org/packages/Octopus.Client/
Add-Type -Path 'Octopus.Client.dll'

# Octopus variables
$octopusURL = "https://your-octopus-url"
$octopusAPIKey = "API-YOUR-KEY"

$spaceName = "Default" # Name of the Space
$tenantName = "TenantName" # The tenant name
$projectVariableTemplateName = "ProjectTemplateName" # Choose the template Name
$newValue = "NewValue" # Choose a new variable value
$NewValueIsBoundToOctopusVariable=$False # Choose $True if the $newValue is an Octopus variable e.g. #{SomeValue}

$endpoint = New-Object Octopus.Client.OctopusServerEndpoint $octopusURL, $octopusAPIKey
$repository = New-Object Octopus.Client.OctopusRepository $endpoint
$client = New-Object Octopus.Client.OctopusClient $endpoint

try
{
  # Get space
  $space = $repository.Spaces.FindByName($spaceName)
  $spaceRepository = $client.ForSpace($space)

  # Get Tenant
  $tenant = $spaceRepository.Tenants.FindByName($tenantName)

  # Get Project Tenant Variables (including missing variables)
  $projectVariablesRequest = New-Object Octopus.Client.Model.TenantVariables.GetProjectVariablesByTenantIdRequest($tenant.Id, $space.Id)
  $projectVariablesRequest.IncludeMissingVariables = $true
  $projectVariables = $spaceRepository.TenantVariables.Get($projectVariablesRequest)

  # Build update payload
  $variablesToModify = @()

  # Loop through project variables
  foreach ($variable in $projectVariables.Variables) {
    if ($variable.Template.Name -eq $projectVariableTemplateName) {
      Write-Host "Found project variable template: $projectVariableTemplateName (Template ID: $($variable.Template.Id), Project ID: $($variable.ProjectId))"

      # Handle sensitive values
      if($variable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
        if($NewValueIsBoundToOctopusVariable -eq $True) {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
        } else {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource
          $newPropertyValue.SensitiveValue = @{
            HasValue = $true
            NewValue = $newValue
          }
          $newPropertyValue.IsSensitive = $true
        }
        Write-Host "Updated sensitive variable for environments: $($variable.Scope.EnvironmentIds -join ', ')"
      } else {
        $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
        Write-Host "Updated variable value to '$newValue' for environments: $($variable.Scope.EnvironmentIds -join ', ')"
      }

      # Create new payload entry
      $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantProjectVariablePayload(
      $variable.ProjectId,
      $variable.TemplateId,
      $newPropertyValue,
      $variable.Scope
      )

      $variablesToModify += $variablePayload
    } else {
      # Keep existing variables unchanged
      $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantProjectVariablePayload(
      $variable.ProjectId,
      $variable.TemplateId,
      $variable.Value,
      $variable.Scope
      )
      $variablePayload.Id = $variable.Id

      $variablesToModify += $variablePayload
    }
  }

  # Handle variables that need to be created
  if ($projectVariables.MissingVariables) {
    foreach ($missingVariable in $projectVariables.MissingVariables) {
      if ($missingVariable.Template.Name -eq $projectVariableTemplateName) {
        Write-Host "Found missing project variable template: $projectVariableTemplateName (Template ID: $($missingVariable.Template.Id), Project ID: $($missingVariable.ProjectId))"

        # Handle sensitive values
        if($missingVariable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
          if($NewValueIsBoundToOctopusVariable -eq $True) {
            $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
          } else {
            $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource
            $newPropertyValue.SensitiveValue = @{
              HasValue = $true
              NewValue = $newValue
            }
            $newPropertyValue.IsSensitive = $true
          }
          Write-Host "Created sensitive variable for missing template"
        } else {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
          Write-Host "Created variable value '$newValue' for missing template"
        }

        # Create new payload entry for missing variable
        $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantProjectVariablePayload(
        $missingVariable.ProjectId,
        $missingVariable.TemplateId,
        $newPropertyValue,
        $missingVariable.Scope
        )

        $variablesToModify += $variablePayload
      }
    }
  }

  # Update project variables
  $modifyProjectCommand = New-Object Octopus.Client.Model.TenantVariables.ModifyProjectVariablesByTenantIdCommand($tenant.Id, $space.Id, $variablesToModify)
  $spaceRepository.TenantVariables.Modify($modifyProjectCommand) | Out-Null
  Write-Host "Successfully updated project tenant variables"
}
catch
{
    Write-Host $_.Exception.Message
}
C#
// If using .net Core, be sure to add the NuGet package of System.Security.Permissions
#r "nuget: Octopus.Client"

using Octopus.Client;
using Octopus.Client.Model;
using Octopus.Client.Model.TenantVariables;

var octopusURL = "https://your-octopus-url";
var octopusAPIKey = "API-YOUR-KEY";
var spaceName = "Default";
var tenantName = "TenantName";
var projectVariableTemplateName = "ProjectTemplateName";
var variableNewValue = "NewValue";
var valueBoundToOctoVariable = false;

// Create repository object
var endpoint = new OctopusServerEndpoint(octopusURL, octopusAPIKey);
var repository = new OctopusRepository(endpoint);
var client = new OctopusClient(endpoint);

try
{
    // Get space
    var space = repository.Spaces.FindByName(spaceName);
    var repositoryForSpace = client.ForSpace(space);

    // Get Tenant
    var tenant = repositoryForSpace.Tenants.FindByName(tenantName);

    // Get Project Tenant Variables (including missing variables)
    var projectVariablesRequest = new GetProjectVariablesByTenantIdRequest(tenant.Id, space.Id)
    {
        IncludeMissingVariables = true
    };

    var projectVariables = repositoryForSpace.TenantVariables.Get(projectVariablesRequest);

    // Build update payload
    var variablesToModify = new List<TenantProjectVariablePayload>();

    // Loop through project variables
    foreach (var variable in projectVariables.Variables)
    {
        if (variable.Template.Name == projectVariableTemplateName)
        {
            Console.WriteLine($"Found project variable template: {projectVariableTemplateName} (Template ID: {variable.Template.Id}, Project ID: {variable.ProjectId})");

            PropertyValueResource newPropertyValue;

            // Handle sensitive values
            if (variable.Template.DisplaySettings.ContainsKey("Octopus.ControlType") &&
                variable.Template.DisplaySettings["Octopus.ControlType"] == "Sensitive")
            {
                if (NewValueIsBoundToOctopusVariable)
                {
                    newPropertyValue = new PropertyValueResource(newValue, false);
                }
                else
                {
                    newPropertyValue = new PropertyValueResource(newValue, true);
                }
                Console.WriteLine($"Updated sensitive variable for environments: {string.Join(", ", variable.Scope.EnvironmentIds)}");
            }
            else
            {
                newPropertyValue = new PropertyValueResource(newValue, false);
                Console.WriteLine($"Updated variable value to '{newValue}' for environments: {string.Join(", ", variable.Scope.EnvironmentIds)}");
            }

            // Create new payload entry
            var variablePayload = new TenantProjectVariablePayload(
                variable.ProjectId,
                variable.TemplateId,
                newPropertyValue,
                variable.Scope
            );

            variablesToModify.Add(variablePayload);
        }
        else
        {
            // Keep existing variables unchanged
            var variablePayload = new TenantProjectVariablePayload(
                variable.ProjectId,
                variable.TemplateId,
                variable.Value,
                variable.Scope
            )
            {
                Id = variable.Id
            };

            variablesToModify.Add(variablePayload);
        }
    }

    // Handle variables that need to be created
    if (projectVariables.MissingVariables != null)
    {
        foreach (var missingVariable in projectVariables.MissingVariables)
        {
            if (missingVariable.Template.Name == projectVariableTemplateName)
            {
                Console.WriteLine($"Found missing project variable template: {projectVariableTemplateName} (Template ID: {missingVariable.Template.Id}, Project ID: {missingVariable.ProjectId})");

                PropertyValueResource newPropertyValue;

                // Handle sensitive values
                if (missingVariable.Template.DisplaySettings.ContainsKey("Octopus.ControlType") &&
                    missingVariable.Template.DisplaySettings["Octopus.ControlType"] == "Sensitive")
                {
                    if (NewValueIsBoundToOctopusVariable)
                    {
                        newPropertyValue = new PropertyValueResource(newValue, false);
                    }
                    else
                    {
                        // For sensitive variables, use the isSensitive parameter
                        newPropertyValue = new PropertyValueResource(newValue, true);
                    }
                    Console.WriteLine("Created sensitive variable for missing template");
                }
                else
                {
                    newPropertyValue = new PropertyValueResource(newValue, false);
                    Console.WriteLine($"Created variable value '{newValue}' for missing template");
                }

                // Create new payload entry for missing variable
                var variablePayload = new TenantProjectVariablePayload(
                    missingVariable.ProjectId,
                    missingVariable.TemplateId,
                    newPropertyValue,
                    missingVariable.Scope
                );

                variablesToModify.Add(variablePayload);
            }
        }
    }

    // Update project variables
    var modifyProjectCommand = new ModifyProjectVariablesByTenantIdCommand(tenant.Id, space.Id, variablesToModify.ToArray());
    repositoryForSpace.TenantVariables.Modify(modifyProjectCommand);
    Console.WriteLine("Successfully updated project tenant variables");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    return;
}
Python3
import json
import requests

def get_octopus_resource(uri, headers, skip_count = 0):
    items = []
    skip_querystring = ""

    if '?' in uri:
        skip_querystring = '&skip='
    else:
        skip_querystring = '?skip='

    response = requests.get((uri + skip_querystring + str(skip_count)), headers=headers)
    response.raise_for_status()

    # Get results of API call
    results = json.loads(response.content.decode('utf-8'))

    # Store results
    if 'Items' in results.keys():
        items += results['Items']

        # Check to see if there are more results
        if (len(results['Items']) > 0) and (len(results['Items']) == results['ItemsPerPage']):
            skip_count += results['ItemsPerPage']
            items += get_octopus_resource(uri, headers, skip_count)

    else:
        return results

    return items

octopus_server_uri = 'https://your-octopus-url'
octopus_api_key = 'API-YOUR-KEY'
headers = {'X-Octopus-ApiKey': octopus_api_key}
space_name = "Default"
tenant_name = "MyTenant"
project_variable_template_name = "ProjectTemplateName"
new_value = "MyValue"
new_value_bound_to_octopus_variable = False

# Get space
uri = f'{octopus_server_uri}/api/spaces'
spaces = get_octopus_resource(uri, headers)
space = next((x for x in spaces if x['Name'] == space_name), None)

# Get Tenant
uri = '{0}/api/{1}/tenants'.format(octopus_server_uri, space['Id'])
tenants = get_octopus_resource(uri, headers)
tenant = next((t for t in tenants if t['Name'] == tenant_name), None)

# Get Project Tenant Variables (including missing variables)
uri = '{0}/api/{1}/tenants/{2}/projectvariables?includeMissingVariables=true'.format(octopus_server_uri, space['Id'], tenant['Id'])
project_variables = requests.get(uri, headers=headers).json()

update_payload = {
    'Variables': []
}

# Loop through project variables
for variable in project_variables['Variables']:
    if variable['Template']['Name'] == project_variable_template_name:
        print(f"Found project variable template: {project_variable_template_name} (Template ID: {variable['Template']['Id']}, Project ID: {variable['ProjectId']})")

        # Create new variable entry
        variable_entry = {
            'ProjectId': variable['ProjectId'],
            'TemplateId': variable['Template']['Id'],
            'Scope': {
                'EnvironmentIds': variable['Scope']['EnvironmentIds']
            }
        }

        # Handle sensitive values
        if variable['Template']['DisplaySettings'].get('Octopus.ControlType') == 'Sensitive':
            if new_value_is_bound_to_octopus_variable:
                variable_entry['Value'] = new_value
            else:
                variable_entry['Value'] = {
                    'HasValue': True,
                    'NewValue': new_value
                }
            print(f"Updated sensitive variable for environments: {', '.join(variable['Scope']['EnvironmentIds'])}")
        else:
            variable_entry['Value'] = new_value
            print(f"Updated variable value to '{new_value}' for environments: {', '.join(variable['Scope']['EnvironmentIds'])}")

        update_payload['Variables'].append(variable_entry)
    else:
        # Keep existing variables unchanged
        update_payload['Variables'].append({
            'Id': variable['Id'],
            'ProjectId': variable['ProjectId'],
            'TemplateId': variable['TemplateId'],
            'Value': variable['Value'],
            'Scope': variable['Scope']
        })

# Handle variables that need to be created
if 'MissingVariables' in project_variables and project_variables['MissingVariables']:
    for missing_variable in project_variables['MissingVariables']:
        if missing_variable['Template']['Name'] == project_variable_template_name:
            print(f"Found missing project variable template: {project_variable_template_name} (Template ID: {missing_variable['Template']['Id']}, Project ID: {missing_variable['ProjectId']})")

            # Create new variable entry for missing variable
            variable_entry = {
                'ProjectId': missing_variable['ProjectId'],
                'TemplateId': missing_variable['Template']['Id'],
                'Scope': {
                    'EnvironmentIds': missing_variable['Scope']['EnvironmentIds']
                }
            }

            # Handle sensitive values
            if missing_variable['Template']['DisplaySettings'].get('Octopus.ControlType') == 'Sensitive':
                if new_value_is_bound_to_octopus_variable:
                    variable_entry['Value'] = new_value
                else:
                    variable_entry['Value'] = {
                        'HasValue': True,
                        'NewValue': new_value
                    }
                print("Created sensitive variable for missing template")
            else:
                variable_entry['Value'] = new_value
                print(f"Created variable value '{new_value}' for missing template")

            update_payload['Variables'].append(variable_entry)

# Update project variables
response = requests.put(f'{octopus_server_uri}/api/{space["Id"]}/tenants/{tenant["Id"]}/projectvariables', headers=headers, json=update_payload)
response.raise_for_status()
print("Successfully updated project tenant variables")

Update common tenant variables

Provide values for:

  • Octopus URL
  • Octopus API Key
  • Name of the space to use
  • Name of the tenant
  • Name of the Library template
  • The new variable value
  • Choose whether the new variable value is bound to an Octopus variable value e.g. #{MyVariable}
PowerShell (REST API)
$ErrorActionPreference = "Stop";

# Define working variables
$octopusURL = "https://your-octopus-url"
$octopusAPIKey = "API-YOUR-KEY"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }

$spaceName = "Default" # Name of the space
$tenantName = "TenantName" # The tenant name
$commonVariableTemplateName = "CommonTemplateName" # Choose the template name
$newValue = "NewValue" # Choose a new variable value, assumes same per environment
$NewValueIsBoundToOctopusVariable=$False # Choose $True if the $newValue is an Octopus variable e.g. #{SomeValue}

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

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

# Get Common Tenant Variables (including missing variables)
$commonVariablesUri = "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/commonvariables?includeMissingVariables=true"
$commonVariables = (Invoke-RestMethod -Method Get -Uri $commonVariablesUri -Headers $header)

# Build update payload
$updatePayload = @{
  Variables = @()
}

# Loop through common variables
foreach ($variable in $commonVariables.Variables) {
  if ($variable.Template.Name -eq $commonVariableTemplateName) {
    Write-Host "Found common variable template: $commonVariableTemplateName (Template ID: $($variable.Template.Id), Library Variable Set ID: $($variable.LibraryVariableSetId))"

    # Create new variable entry
    $variableEntry = @{
      LibraryVariableSetId = $variable.LibraryVariableSetId
      TemplateId = $variable.Template.Id
      Scope = @{
        EnvironmentIds = $variable.Scope.EnvironmentIds
      }
    }

    # Handle sensitive values
    if($variable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
      if($NewValueIsBoundToOctopusVariable -eq $True) {
        $variableEntry.Value = $newValue
      } else {
        $variableEntry.Value = @{
          HasValue = $true
          NewValue = $newValue
        }
      }
      Write-Host "Updated sensitive variable for environments: $($variable.Scope.EnvironmentIds -join ', ')"
    } else {
      $variableEntry.Value = $newValue
      Write-Host "Updated variable value to '$newValue' for environments: $($variable.Scope.EnvironmentIds -join ', ')"
    }

    $updatePayload.Variables += $variableEntry
  } else {
    # Keep existing variables unchanged
    $updatePayload.Variables += @{
      Id = $variable.Id
      LibraryVariableSetId = $variable.LibraryVariableSetId
      TemplateId = $variable.TemplateId
      Value = $variable.Value
      Scope = $variable.Scope
    }
  }
}

# Handle variables that need to be created
if ($commonVariables.MissingVariables) {
  foreach ($missingVariable in $commonVariables.MissingVariables) {
    if ($missingVariable.Template.Name -eq $commonVariableTemplateName) {
      Write-Host "Found missing common variable template: $commonVariableTemplateName (Template ID: $($missingVariable.Template.Id), Library Variable Set ID: $($missingVariable.LibraryVariableSetId))"

      # Create new variable entry for missing variable
      $variableEntry = @{
        LibraryVariableSetId = $missingVariable.LibraryVariableSetId
        TemplateId = $missingVariable.Template.Id
        Scope = @{
          EnvironmentIds = $missingVariable.Scope.EnvironmentIds
        }
      }

      # Handle sensitive values
      if($missingVariable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
        if($NewValueIsBoundToOctopusVariable -eq $True) {
          $variableEntry.Value = $newValue
        } else {
          $variableEntry.Value = @{
            HasValue = $true
            NewValue = $newValue
          }
        }
        Write-Host "Created sensitive variable for missing template"
      } else {
        $variableEntry.Value = $newValue
        Write-Host "Created variable value '$newValue' for missing template"
      }

      $updatePayload.Variables += $variableEntry
    }
  }
}

# Update common variables
Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/commonvariables" -Headers $header -Body ($updatePayload | ConvertTo-Json -Depth 10)
Write-Host "Successfully updated common tenant variables"
PowerShell (Octopus.Client)
# You can get this dll from your Octopus Server/Tentacle installation directory or from
# https://www.nuget.org/packages/Octopus.Client/
Add-Type -Path 'Octopus.Client.dll'

# Octopus variables
$octopusURL = "https://your-octopus-url"
$octopusAPIKey = "API-YOUR-KEY"

$spaceName = "Default" # Name of the Space
$tenantName = "TenantName" # The tenant name
$commonVariableTemplateName = "CommonTemplateName" # Choose the template Name
$newValue = "NewValue" # Choose a new variable value
$NewValueIsBoundToOctopusVariable=$False # Choose $True if the $newValue is an Octopus variable e.g. #{SomeValue}

$endpoint = New-Object Octopus.Client.OctopusServerEndpoint $octopusURL, $octopusAPIKey
$repository = New-Object Octopus.Client.OctopusRepository $endpoint
$client = New-Object Octopus.Client.OctopusClient $endpoint

try
{
  # Get space
  $space = $repository.Spaces.FindByName($spaceName)
  $spaceRepository = $client.ForSpace($space)

  # Get Tenant
  $tenant = $spaceRepository.Tenants.FindByName($tenantName)

  # Get Common Tenant Variables (including missing variables)
  $commonVariablesRequest = New-Object Octopus.Client.Model.TenantVariables.GetCommonVariablesByTenantIdRequest($tenant.Id, $space.Id)
  $commonVariablesRequest.IncludeMissingVariables = $true
  $commonVariables = $spaceRepository.TenantVariables.Get($commonVariablesRequest)

  # Build update payload
  $variablesToModify = @()

  # Loop through common variables
  foreach ($variable in $commonVariables.Variables) {
    if ($variable.Template.Name -eq $commonVariableTemplateName) {
      Write-Host "Found common variable template: $commonVariableTemplateName (Template ID: $($variable.Template.Id), Library Variable Set ID: $($variable.LibraryVariableSetId))"

      # Handle sensitive values
      if($variable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
        if($NewValueIsBoundToOctopusVariable -eq $True) {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
        } else {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $true)
        }
        Write-Host "Updated sensitive variable for environments: $($variable.Scope.EnvironmentIds -join ', ')"
      } else {
        $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
        Write-Host "Updated variable value to '$newValue' for environments: $($variable.Scope.EnvironmentIds -join ', ')"
      }

      # Create new payload entry
      $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantCommonVariablePayload(
      $variable.LibraryVariableSetId,
      $variable.TemplateId,
      $newPropertyValue,
      $variable.Scope
      )

      $variablesToModify += $variablePayload
    } else {
      # Keep existing variables unchanged
      $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantCommonVariablePayload(
      $variable.LibraryVariableSetId,
      $variable.TemplateId,
      $variable.Value,
      $variable.Scope
      )
      $variablePayload.Id = $variable.Id

      $variablesToModify += $variablePayload
    }
  }

  # Handle variables that need to be created
  if ($commonVariables.MissingVariables) {
    foreach ($missingVariable in $commonVariables.MissingVariables) {
      if ($missingVariable.Template.Name -eq $commonVariableTemplateName) {
        Write-Host "Found missing common variable template: $commonVariableTemplateName (Template ID: $($missingVariable.Template.Id), Library Variable Set ID: $($missingVariable.LibraryVariableSetId))"

        # Handle sensitive values
        if($missingVariable.Template.DisplaySettings["Octopus.ControlType"] -eq "Sensitive") {
          if($NewValueIsBoundToOctopusVariable -eq $True) {
            $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
          } else {
            $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $true)
          }
          Write-Host "Created sensitive variable for missing template"
        } else {
          $newPropertyValue = New-Object Octopus.Client.Model.PropertyValueResource($newValue, $false)
          Write-Host "Created variable value '$newValue' for missing template"
        }

        # Create new payload entry for missing variable
        $variablePayload = New-Object Octopus.Client.Model.TenantVariables.TenantCommonVariablePayload(
        $missingVariable.LibraryVariableSetId,
        $missingVariable.TemplateId,
        $newPropertyValue,
        $missingVariable.Scope
        )

        $variablesToModify += $variablePayload
      }
    }
  }

  # Update common variables
  $modifyCommonCommand = New-Object Octopus.Client.Model.TenantVariables.ModifyCommonVariablesByTenantIdCommand($tenant.Id, $space.Id, $variablesToModify)
  $spaceRepository.TenantVariables.Modify($modifyCommonCommand) | Out-Null
  Write-Host "Successfully updated common tenant variables"
}
catch
{
    Write-Host $_.Exception.Message
}
C#
// If using .net Core, be sure to add the NuGet package of System.Security.Permissions
#r "nuget: Octopus.Client"

using Octopus.Client;
using Octopus.Client.Model;
using Octopus.Client.Model.TenantVariables;

var octopusURL = "https://your-octopus-url";
var octopusAPIKey = "API-YOUR-KEY";
var spaceName = "Default";
var tenantName = "TenantName";
var commonVariableTemplateName = "CommonTemplateName";
var newValue = "NewValue";
var newValueIsBoundToOctopusVariable = false;

// Create repository object
var endpoint = new OctopusServerEndpoint(octopusURL, octopusAPIKey);
var repository = new OctopusRepository(endpoint);
var client = new OctopusClient(endpoint);

try
{
    // Get space
    var space = repository.Spaces.FindByName(spaceName);
    var repositoryForSpace = client.ForSpace(space);

    // Get Tenant
    var tenant = repositoryForSpace.Tenants.FindByName(tenantName);

    // Get Common Tenant Variables (including missing variables)
    var commonVariablesRequest = new GetCommonVariablesByTenantIdRequest(tenant.Id, space.Id)
    {
        IncludeMissingVariables = true
    };

    var commonVariables = repositoryForSpace.TenantVariables.Get(commonVariablesRequest);

    // Build update payload
    var variablesToModify = new List<TenantCommonVariablePayload>();

    // Loop through common variables
    foreach (var variable in commonVariables.Variables)
    {
        if (variable.Template.Name == commonVariableTemplateName)
        {
            Console.WriteLine($"Found common variable template: {commonVariableTemplateName} (Template ID: {variable.Template.Id}, Library Variable Set ID: {variable.LibraryVariableSetId})");

            PropertyValueResource newPropertyValue;

            // Handle sensitive values
            if (variable.Template.DisplaySettings.ContainsKey("Octopus.ControlType") &&
                variable.Template.DisplaySettings["Octopus.ControlType"] == "Sensitive")
            {
                if (newValueIsBoundToOctopusVariable)
                {
                    newPropertyValue = new PropertyValueResource(newValue, false);
                }
                else
                {
                    newPropertyValue = new PropertyValueResource(newValue, true);
                }
                Console.WriteLine($"Updated sensitive variable for environments: {string.Join(", ", variable.Scope.EnvironmentIds)}");
            }
            else
            {
                newPropertyValue = new PropertyValueResource(newValue, false);
                Console.WriteLine($"Updated variable value to '{newValue}' for environments: {string.Join(", ", variable.Scope.EnvironmentIds)}");
            }

            // Create new payload entry
            var variablePayload = new TenantCommonVariablePayload(
                variable.LibraryVariableSetId,
                variable.TemplateId,
                newPropertyValue,
                variable.Scope
            );

            variablesToModify.Add(variablePayload);
        }
        else
        {
            // Keep existing variables unchanged
            var variablePayload = new TenantCommonVariablePayload(
                variable.LibraryVariableSetId,
                variable.TemplateId,
                variable.Value,
                variable.Scope
            )
            {
                Id = variable.Id
            };

            variablesToModify.Add(variablePayload);
        }
    }

    // Handle variables that need to be created
    if (commonVariables.MissingVariables != null)
    {
        foreach (var missingVariable in commonVariables.MissingVariables)
        {
            if (missingVariable.Template.Name == commonVariableTemplateName)
            {
                Console.WriteLine($"Found missing common variable template: {commonVariableTemplateName} (Template ID: {missingVariable.Template.Id}, Library Variable Set ID: {missingVariable.LibraryVariableSetId})");

                PropertyValueResource newPropertyValue;

                // Handle sensitive values
                if (missingVariable.Template.DisplaySettings.ContainsKey("Octopus.ControlType") &&
                    missingVariable.Template.DisplaySettings["Octopus.ControlType"] == "Sensitive")
                {
                    if (newValueIsBoundToOctopusVariable)
                    {
                        newPropertyValue = new PropertyValueResource(newValue, false);
                    }
                    else
                    {
                        newPropertyValue = new PropertyValueResource(newValue, true);
                    }
                    Console.WriteLine("Created sensitive variable for missing template");
                }
                else
                {
                    newPropertyValue = new PropertyValueResource(newValue, false);
                    Console.WriteLine($"Created variable value '{newValue}' for missing template");
                }

                // Create new payload entry for missing variable
                var variablePayload = new TenantCommonVariablePayload(
                    missingVariable.LibraryVariableSetId,
                    missingVariable.TemplateId,
                    newPropertyValue,
                    missingVariable.Scope
                );

                variablesToModify.Add(variablePayload);
            }
        }
    }

    // Update common variables
    var modifyCommonCommand = new ModifyCommonVariablesByTenantIdCommand(tenant.Id, space.Id, variablesToModify.ToArray());
    repositoryForSpace.TenantVariables.Modify(modifyCommonCommand);
    Console.WriteLine("Successfully updated common tenant variables");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
    return;
}
Python3
import json
import requests

def get_octopus_resource(uri, headers, skip_count = 0):
    items = []
    skip_querystring = ""

    if '?' in uri:
        skip_querystring = '&skip='
    else:
        skip_querystring = '?skip='

    response = requests.get((uri + skip_querystring + str(skip_count)), headers=headers)
    response.raise_for_status()

    # Get results of API call
    results = json.loads(response.content.decode('utf-8'))

    # Store results
    if 'Items' in results.keys():
        items += results['Items']

        # Check to see if there are more results
        if (len(results['Items']) > 0) and (len(results['Items']) == results['ItemsPerPage']):
            skip_count += results['ItemsPerPage']
            items += get_octopus_resource(uri, headers, skip_count)

    else:
        return results

    return items

octopus_server_uri = 'https://your-octopus-url'
octopus_api_key = 'API-YOUR-KEY'
headers = {'X-Octopus-ApiKey': octopus_api_key}
space_name = "Default"
tenant_name = "MyTenant"
common_variable_template_name = "CommonTemplateName"
new_value = "MyValue"
new_value_bound_to_octopus_variable = False

# Get space
uri = f'{octopus_server_uri}/api/spaces'
spaces = get_octopus_resource(uri, headers)
space = next((x for x in spaces if x['Name'] == space_name), None)

# Get Tenant
uri = '{0}/api/{1}/tenants'.format(octopus_server_uri, space['Id'])
tenants = get_octopus_resource(uri, headers)
tenant = next((t for t in tenants if t['Name'] == tenant_name), None)

# Get Common Tenant Variables (including missing variables)
uri = '{0}/api/{1}/tenants/{2}/commonvariables?includeMissingVariables=true'.format(octopus_server_uri, space['Id'], tenant['Id'])
common_variables = requests.get(uri, headers=headers).json()

update_payload = {
    'Variables': []
}

# Loop through common variables
for variable in common_variables['Variables']:
    if variable['Template']['Name'] == common_variable_template_name:
        print(f"Found common variable template: {common_variable_template_name} (Template ID: {variable['Template']['Id']}, Library Variable Set ID: {variable['LibraryVariableSetId']})")

        # Create new variable entry
        variable_entry = {
            'LibraryVariableSetId': variable['LibraryVariableSetId'],
            'TemplateId': variable['Template']['Id'],
            'Scope': {
                'EnvironmentIds': variable['Scope']['EnvironmentIds']
            }
        }

        # Handle sensitive values
        if variable['Template']['DisplaySettings'].get('Octopus.ControlType') == 'Sensitive':
            if new_value_bound_to_octopus_variable:
                variable_entry['Value'] = new_value
            else:
                variable_entry['Value'] = {
                    'HasValue': True,
                    'NewValue': new_value
                }
            print(f"Updated sensitive variable for environments: {', '.join(variable['Scope']['EnvironmentIds'])}")
        else:
            variable_entry['Value'] = new_value
            print(f"Updated variable value to '{new_value}' for environments: {', '.join(variable['Scope']['EnvironmentIds'])}")

        update_payload['Variables'].append(variable_entry)
    else:
        # Keep existing variables unchanged
        update_payload['Variables'].append({
            'Id': variable['Id'],
            'LibraryVariableSetId': variable['LibraryVariableSetId'],
            'TemplateId': variable['TemplateId'],
            'Value': variable['Value'],
            'Scope': variable['Scope']
        })

# Handle variables that need to be created
if 'MissingVariables' in common_variables and common_variables['MissingVariables']:
    for missing_variable in common_variables['MissingVariables']:
        if missing_variable['Template']['Name'] == common_variable_template_name:
            print(f"Found missing common variable template: {common_variable_template_name} (Template ID: {missing_variable['Template']['Id']}, Library Variable Set ID: {missing_variable['LibraryVariableSetId']})")

            # Create new variable entry for missing variable
            variable_entry = {
                'LibraryVariableSetId': missing_variable['LibraryVariableSetId'],
                'TemplateId': missing_variable['Template']['Id'],
                'Scope': {
                    'EnvironmentIds': missing_variable['Scope']['EnvironmentIds']
                }
            }

            # Handle sensitive values
            if missing_variable['Template']['DisplaySettings'].get('Octopus.ControlType') == 'Sensitive':
                if new_value_bound_to_octopus_variable:
                    variable_entry['Value'] = new_value
                else:
                    variable_entry['Value'] = {
                        'HasValue': True,
                        'NewValue': new_value
                    }
                print("Created sensitive variable for missing template")
            else:
                variable_entry['Value'] = new_value
                print(f"Created variable value '{new_value}' for missing template")

            update_payload['Variables'].append(variable_entry)

# Update common variables
response = requests.put(f'{octopus_server_uri}/api/{space["Id"]}/tenants/{tenant["Id"]}/commonvariables', headers=headers, json=update_payload)
response.raise_for_status()
print("Successfully updated common tenant variables")

Help us continuously improve

Please let us know if you have any feedback about this page.

Send feedback

Page updated on Tuesday, January 20, 2026

Use Octopus docs with AI