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.
Page updated on Tuesday, January 20, 2026