diff --git a/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables-update.mdx b/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables-update.mdx
index a100b06bb7..ef3b476e65 100644
--- a/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables-update.mdx
+++ b/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables-update.mdx
@@ -1,7 +1,7 @@
---
layout: src/layouts/Default.astro
pubDate: 2023-01-01
-modDate: 2025-05-07
+modDate: 2026-01-20
title: octopus tenant variables update
description: Update the value of a tenant variable
navOrder: 145
@@ -10,7 +10,7 @@ import SamplesInstance from 'src/shared-content/samples/samples-instance.include
Update the value of a tenant variable in Octopus Deploy
-```
+```text
Usage:
octopus tenant variables update [flags]
@@ -35,10 +35,24 @@ Global Flags:
-```
+```bash
+# Interactive mode - prompts for all required values
$ octopus tenant variables update
+
+# Update a project variable for a specific environment (single environment scope)
$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "site-name" --value "Bob's Fish Shack" --project "Awesome Web Site" --environment "Test"
-$ octopus tenant variables update --tenant "Sally's Tackle Truck" --name dbPassword --value "12345" --library-variable-set "Shared Variables"
+
+# Update a project variable for multiple environments (multiple environment scopes)
+$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "database-server" --value "prod-db-01" --project "Awesome Web Site" --environment "Staging" --environment "Production"
+
+# Update a project variable for all environments (unscoped - omit --environment flag)
+$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "app-name" --value "Bobs App" --project "Awesome Web Site"
+
+# Update a common variable from a library variable set
+$ octopus tenant variables update --tenant "Sally's Tackle Truck" --name "dbPassword" --value "12345" --library-variable-set "Shared Variables"
+
+# Update a common variable with environment scoping
+$ octopus tenant variables update --tenant "Sally's Tackle Truck" --name "api-key" --value "prod-key-123" --library-variable-set "API Config" --environment "Production"
```
@@ -46,4 +60,4 @@ $ octopus tenant variables update --tenant "Sally's Tackle Truck" --name dbPassw
## Learn more
- [Octopus CLI](/docs/octopus-rest-api/cli)
-- [Creating API keys](/docs/octopus-rest-api/how-to-create-an-api-key)
\ No newline at end of file
+- [Creating API keys](/docs/octopus-rest-api/how-to-create-an-api-key)
diff --git a/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables.mdx b/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables.mdx
index 8436c54d78..00205afa2d 100644
--- a/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables.mdx
+++ b/src/pages/docs/octopus-rest-api/cli/octopus-tenant-variables.mdx
@@ -1,7 +1,7 @@
---
layout: src/layouts/Default.astro
pubDate: 2023-01-01
-modDate: 2025-05-07
+modDate: 2026-01-20
title: octopus tenant variables
description: Manage tenant variables
navOrder: 143
@@ -10,7 +10,7 @@ import SamplesInstance from 'src/shared-content/samples/samples-instance.include
Manage tenant variables in Octopus Deploy
-```
+```text
Usage:
octopus tenant variables [command]
@@ -36,14 +36,17 @@ Use "octopus tenant variables [command] --help" for more information about a com
-```
+```bash
$ octopus tenant variables list "Bobs Wood Shop"
-$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "site-name" --value "Bob's Fish Shack" --project "Awesome Web Site" --environment "Test"
+# Update a project variable for a specific environment (single environment scope)
+$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "site-name" --value "Bob's Fish Shack" --project "Awesome Web Site" --environment "Test"
+# Update a common variable from a library variable set for specific environments
+$ octopus tenant variables update --tenant "Bobs Fish Shack" --name "company-logo" --value "bobs-logo.png" --library-variable-set "Shared Assets" --environment "Production"
```
## Learn more
- [Octopus CLI](/docs/octopus-rest-api/cli)
-- [Creating API keys](/docs/octopus-rest-api/how-to-create-an-api-key)
\ No newline at end of file
+- [Creating API keys](/docs/octopus-rest-api/how-to-create-an-api-key)
diff --git a/src/pages/docs/octopus-rest-api/examples/tenants/update-tenant-variable.mdx b/src/pages/docs/octopus-rest-api/examples/tenants/update-tenant-variable.mdx
index ad56bd4d27..5c2aa79d8f 100644
--- a/src/pages/docs/octopus-rest-api/examples/tenants/update-tenant-variable.mdx
+++ b/src/pages/docs/octopus-rest-api/examples/tenants/update-tenant-variable.mdx
@@ -1,15 +1,16 @@
---
layout: src/layouts/Default.astro
pubDate: 2023-01-01
-modDate: 2023-01-01
+modDate: 2026-01-20
title: Update tenant variables
-description: An example script that updates tenant variables for a specific project template with a single value across each connected environment in Octopus using the REST API and Octopus.Client.
+description: Example scripts that update tenant variables for both project variables and common (library) variables in Octopus using the REST API and Octopus.Client.
---
-import UpdateTenantVariableScripts from 'src/shared-content/scripts/update-tenant-variable-scripts.include.md';
+import UpdateTenantProjectVariableScripts from 'src/shared-content/scripts/update-tenant-project-variable-scripts.include.md';
+import UpdateTenantCommonVariableScripts from 'src/shared-content/scripts/update-tenant-common-variable-scripts.include.md';
-This script demonstrates how to programmatically update tenant variables with a single value across each connected environment in Octopus.
+These scripts demonstrate how to programmatically update tenant variables.
-## Usage
+## Update project tenant variables
Provide values for:
@@ -21,6 +22,18 @@ Provide values for:
- The new variable value
- Choose whether the new variable value is bound to an Octopus variable value e.g. `#{MyVariable}`
-## Script
+
-
+## 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}`
+
+
diff --git a/src/shared-content/scripts/update-tenant-common-variable-scripts.include.md b/src/shared-content/scripts/update-tenant-common-variable-scripts.include.md
new file mode 100644
index 0000000000..b0e46409bb
--- /dev/null
+++ b/src/shared-content/scripts/update-tenant-common-variable-scripts.include.md
@@ -0,0 +1,539 @@
+
+PowerShell (REST API)
+
+```powershell
+$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)
+
+```powershell
+# 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#
+
+```csharp
+// 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();
+
+ // 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
+
+```python
+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")
+```
+
+
diff --git a/src/shared-content/scripts/update-tenant-project-variable-scripts.include.md b/src/shared-content/scripts/update-tenant-project-variable-scripts.include.md
new file mode 100644
index 0000000000..d021cb6ce5
--- /dev/null
+++ b/src/shared-content/scripts/update-tenant-project-variable-scripts.include.md
@@ -0,0 +1,550 @@
+
+PowerShell (REST API)
+
+```powershell
+$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)
+
+```powershell
+# 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#
+
+```csharp
+// 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();
+
+ // 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
+
+```python
+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")
+```
+
+
diff --git a/src/shared-content/scripts/update-tenant-variable-scripts.include.md b/src/shared-content/scripts/update-tenant-variable-scripts.include.md
deleted file mode 100644
index 594e9f16aa..0000000000
--- a/src/shared-content/scripts/update-tenant-variable-scripts.include.md
+++ /dev/null
@@ -1,374 +0,0 @@
-
-PowerShell (REST API)
-
-```powershell
-$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
-$variableTemplateName = "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 Tenant Variables
-$variables = (Invoke-RestMethod -Method Get -Uri "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables" -Headers $header)
-
-# Get project templates
-$projects = $variables.ProjectVariables | Get-Member | Where-Object {$_.MemberType -eq "NoteProperty"} | Select-Object -ExpandProperty "Name"
-
-# Loop through each project template
-foreach ($projectKey in $projects)
-{
- # Get connected project
- $project = $variables.ProjectVariables.$projectKey
- $projectName = $project.ProjectName
- Write-Host "Working on Project: $projectName ($projectKey)"
-
- # Get Project template ID
- $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) {
- # 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 "Couldn't find project template: $variableTemplateName for project $projectName"
- }
-}
-# Update the variables with the new value
-Invoke-RestMethod -Method Put -Uri "$octopusURL/api/$($space.Id)/tenants/$($tenant.Id)/variables" -Headers $header -Body ($variables | ConvertTo-Json -Depth 10)
-```
-
-
-
-PowerShell (Octopus.Client)
-
-```powershell
-# 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
-$variableTemplateName = "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}
-
-$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 Tenant Variables
- $variables = $spaceRepository.Tenants.GetVariables($tenant)
-
- # Loop through each Project Template
- foreach($projectKey in $variables.ProjectVariables.Keys)
- {
- # Get connected project
- $project = $variables.ProjectVariables[$projectKey]
- $projectName = $project.ProjectName
- Write-Host "Working on Project: $projectName ($projectKey)"
-
- # Get Project template ID
- $variableTemplate = ($project.Templates | Where-Object Name -eq $variableTemplateName | Select-Object -First 1)
- $variableTemplateId = $variableTemplate.Id
- $variableTemplateIsSensitiveControlType = $variableTemplate.DisplaySettings["Octopus.ControlType"] -eq "Sensitive"
-
- if($null -ne $variableTemplateId) {
-
- Write-Host "Found templateId for Template: $variableTemplateName = $variableTemplateId"
-
- # Loop through each of the connected environments variables
- foreach($envKey in $project.Variables.Keys) {
-
- # Set null value in case not set
- $project.Variables[$envKey][$variableTemplateId] = $null
-
- # 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] = New-Object Octopus.Client.Model.PropertyValueResource $newValue
- }
- else {
- Write-Host "Adding in new sensitive value = '********' in Environment '$envKey' for $variableTemplateName"
- $sensitiveValue = New-Object Octopus.Client.Model.SensitiveValue
- $sensitiveValue.HasValue = $True
- $sensitiveValue.NewValue = $newValue
- $project.Variables[$envKey][$variableTemplateId] = $sensitiveValue
- }
- }
- else {
- Write-Host "Adding in new value = $newValue in Environment '$envKey' for $variableTemplateName"
- $project.Variables[$envKey][$variableTemplateId] = New-Object Octopus.Client.Model.PropertyValueResource $newValue
- }
- }
- }
- else {
- Write-Host "Couldn't find project template: $variableTemplateName for project $projectName"
- }
- }
-
- # Update the variables with the new value
- $spaceRepository.Tenants.ModifyVariables($tenant, $variables) | Out-Null
-}
-catch
-{
- Write-Host $_.Exception.Message
-}
-```
-
-
-
-C#
-
-```csharp
-// 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;
-
-var octopusURL = "https://your-octopus-url";
-var octopusAPIKey = "API-YOUR-KEY";
-var spaceName = "Default";
-var tenantName = "TenantName";
-var projectVariableTemplateName = "TemplateName";
-var variableNewValue = "NewValue";
-var valueBoundToOctoVariable = true;
-
-// 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 tenant variables
- var variables = repositoryForSpace.Tenants.GetVariables(tenant);
-
- // Loop through tenant variables
- foreach (var projectKey in variables.ProjectVariables.Keys)
- {
- var project = variables.ProjectVariables[projectKey];
- var projectName = project.ProjectName;
- Console.WriteLine("Working on Project: {0} ({1})", projectName, projectKey);
-
- // Get project template ID.
- var variableTemplateResource = project.Templates.FirstOrDefault(t => t.Name == projectVariableTemplateName);
-
- if (variableTemplateResource != null)
- {
- var variableTemplateId = variableTemplateResource.Id;
- var variableTemplateIsSensitiveControlType = (variableTemplateResource.DisplaySettings.FirstOrDefault(ds => ds.Key == "Octopus.ControlType")).Value == "Sensitive";
- Console.WriteLine("Found templateid for template: {0} of {1}", projectVariableTemplateName, variableTemplateId);
-
- // Loop through each of the connected environments
- foreach (var envKey in project.Variables.Keys)
- {
- // Set null value in case not set
- project.Variables[envKey][variableTemplateId] = null;
-
- if (variableTemplateIsSensitiveControlType == true)
- {
- if (valueBoundToOctoVariable == true)
- {
- Console.WriteLine("Adding in new text value (treating as octopus variable) in Environment '{0}' for {1}", envKey, projectVariableTemplateName);
- project.Variables[envKey][variableTemplateId] = new PropertyValueResource(variableNewValue);
- }
- else
- {
- Console.WriteLine("Adding in new sensitive value = '********' in Environment '{0}' for {1}", envKey, projectVariableTemplateName);
- var sensitiveValue = new SensitiveValue { HasValue = true, NewValue = variableNewValue };
- project.Variables[envKey][variableTemplateId] = new PropertyValueResource(sensitiveValue);
- }
- }
- else
- {
- //Write-Host "Adding in new value = $newValue in Environment '$envKey' for $variableTemplateName"
- Console.WriteLine("Adding in new value = '{0}' in Environment '{1}' for {2}", variableNewValue, envKey, projectVariableTemplateName);
- project.Variables[envKey][variableTemplateId] = new PropertyValueResource(variableNewValue);
- }
- }
- }
- else
- {
- Console.WriteLine("Couldn't find project template: {0} for project {1}", projectVariableTemplateName, projectName);
- }
- }
-
- // Update the variables with the new value
- repositoryForSpace.Tenants.ModifyVariables(tenant, variables);
-}
-catch (Exception ex)
-{
- Console.WriteLine(ex.Message);
- return;
-}
-```
-
-
-
-Python3
-
-```python
-import json
-import requests
-from requests.api import get, head
-
-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 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"
-variable_template_name = "Tenant.Site.HostName"
-new_value = "MyValue"
-new_value_bound_to_octopus_variable = False
-
-# Get space
-uri = '{0}/api/spaces'.format(octopus_server_uri)
-spaces = get_octopus_resource(uri, headers)
-space = next((x for x in spaces if x['Name'] == space_name), None)
-
-# Get tenants
-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 tenant variables
-uri = '{0}/api/{1}/tenants/{2}/variables'.format(octopus_server_uri, space['Id'], tenant['Id'])
-tenant_variables = get_octopus_resource(uri, headers)
-variable_template = None
-
-# Loop through connected projects
-for projectKey in tenant_variables['ProjectVariables']:
- templates = tenant_variables['ProjectVariables'][projectKey]['Templates']
-
- # Loop through the project templates
- for template in templates:
- is_sensitive = (template['DisplaySettings']['Octopus.ControlType'] == 'Sensitive')
- if template['Name'] == variable_template_name:
- variable_template = template
- break
-
- if variable_template != None:
- # Loop through connected environments
- environment_variables = tenant_variables['ProjectVariables'][projectKey]['Variables']
-
- for environment_variable in environment_variables:
- variables = tenant_variables['ProjectVariables'][projectKey]['Variables'][environment_variable]
- if is_sensitive:
- new_sensitive_variable = {
- 'HasValue': True,
- 'NewValue': new_value_bound_to_octopus_variable
- }
- variables[variable_template['Id']] = new_sensitive_variable
- else:
- variables[variable_template['Id']] = new_value
-
-# Update the tenants variables
-uri = '{0}/api/{1}/tenants/{2}/variables'.format(octopus_server_uri, space['Id'], tenant['Id'])
-response = requests.put(uri, headers=headers, json=tenant_variables)
-response.raise_for_status()
-```
-
-
\ No newline at end of file