Scoped Project Variables with Powershell

Hello, I am using powershell to create, check and update some project variables. I have a question though, is there a way I can know what environment I’m in (dev, test, etc…) and only pull the scoped value for that environment? The functions I’m using are below…

In the end, I need to see what environment I’m currently in, and create or update my project variable only for that particular scope, leaving the others alone. Thanks in advance for any help!!

Function Update-ProjectVariables
{
param(
$OctopusServerUrl,
$ProjectVariables,
$ApiKey
)

Convert the object into JSON

$jsonBody = $ProjectVariables | ConvertTo-Json -Depth 5

Call the API to update

Invoke-RestMethod -Method “put” -Uri “$OctopusServerUrl/api/variables/$($ProjectVariables.Id)” -Body $jsonBody -Headers @{“X-Octopus-ApiKey”="$ApiKey"}
}

Function Get-OctopusProjectVariables
{
# Define parameters
param(
$OctopusDeployProject,
$OctopusServerUrl,
$ApiKey
)

Get reference to the variable list

return (Invoke-RestMethod -Method “get” -Uri “$OctopusServerUrl/api/variables/$($OctopusDeployProject.VariableSetId)” -Headers @{“X-Octopus-ApiKey”="$ApiKey"})
}

Function Get-OctopusProject
{

Define parameters

param(
$OctopusServerUrl,
$ApiKey,
$ProjectName
)

Call API to get all projects, then filter on name

$octopusProject = Invoke-RestMethod -Method “get” -Uri “$OctopusServerUrl/api/projects/all” -Headers @{“X-Octopus-ApiKey”="$ApiKey"}

return the specific project

return ($octopusProject | Where-Object {$_.Name -eq $ProjectName})
}

Hi @pgruidl,

Thanks for getting in touch! I’m sorry for the delay in getting back to you here. I may need to get some some further information from you to get a better idea of your requirements.

Are you attempting to update these variables during a deployment or task? You mention wanting to see what environment you are currently in. This leads me to believe you are attempting to do this during a deployment.

If you could provide some more context around your requirements and end goal here I can hopefully provide you with a nice solution.

Using the API to manage variables can quickly become complicated and we have many methods within Octopus to help you control your Variables. So I’m wondering if we can get away with a good solution without having to rely on the API.

Looking forward to hearing from you.

Best regards,
Daniel

You are exactly right - I’m trying to update these variables during a deployment. The story is this… there is a dacpac file on these deployments, and i am getting a hash of that artifact, and if the hash matches what is already in octopus, we’ll skip that step. If not… it’ll deploy the dacpac and if its successful, it’ll write the new hash variable to the project. I’ve figured out how to scope variables to particular environments, or so i thought. The issue I’m seeing now is as follows:

Lets say my project has a hash value for 2 environments, lets say development and integration. The deploy is going to development, and lets say the hash does not match, so octopus does the deploy dacpac step and writes the new hash value to the project variables. Problem is… its writing that new value to all environments that have a scoped value. So the hash for the integration environment gets updated upon a successful deploy to development, which obviously shouldnt happen. If there were no values in the project at the time of writing the variable… it looks correct. A hash would get written and be scoped to just the environment it succeeded in.

I cant figure out why it seemingly scopes the variable correctly when there are no values present… but if there are, it writes that value to all scopes.

Let me know what else you need from me if you can help! Thanks!!

Below is some code that I am using:

**The snippet below is creating the new variable… and supposedly scoping it to just the current environment Octopus is running in. **

$newVariable = @{
#Id = “$(New-Guid)”
Name = $dacpac_var
Value = $current_hash
Description = $null
Scope = @{ Environment = $OctopusParameters[“Octopus.Environment.Id”] }
IsEditable = $true
Prompt = $null
Type = “String”
IsSensitive = $false
}
$myproject = Get-OctopusProject -OctopusServerUrl $OctopusURL -ApiKey $OctopusAPIKey -ProjectName $OctopusParameters[“Octopus.Project.Name”]
$projectVars = Get-OctopusProjectVariables -OctopusDeployProject $myproject -OctopusServerUrl $OctopusURL -ApiKey $OctopusAPIKey
$projectVars.Variables += $newVariable
Update-ProjectVariables -ProjectVariables $projectVars -ApiKey $OctopusAPIKey -OctopusServerUrl $OctopusURL

The snippet below are the function declarations that the code above is using.

Function Update-ProjectVariables
{
param(
$OctopusServerUrl,
$ProjectVariables,
$ApiKey
)

Convert the object into JSON

$jsonBody = $ProjectVariables | ConvertTo-Json -Depth 5

Call the API to update

Invoke-RestMethod -Method “put” -Uri “$OctopusServerUrl/api/variables/$($ProjectVariables.Id)” -Body $jsonBody -Headers @{“X-Octopus-ApiKey”="$ApiKey"}
}

Function Get-OctopusProjectVariables
{
# Define parameters
param(
$OctopusDeployProject,
$OctopusServerUrl,
$ApiKey
)

Get reference to the variable list

return (Invoke-RestMethod -Method “get” -Uri “$OctopusServerUrl/api/variables/$($OctopusDeployProject.VariableSetId)” -Headers @{“X-Octopus-ApiKey”="$ApiKey"})
}

Function Get-OctopusProject
{

Define parameters

param(
$OctopusServerUrl,
$ApiKey,
$ProjectName
)

Call API to get all projects, then filter on name

$octopusProject = Invoke-RestMethod -Method “get” -Uri “$OctopusServerUrl/api/projects/all” -Headers @{“X-Octopus-ApiKey”="$ApiKey"}

return the specific project

return ($octopusProject | Where-Object {$_.Name -eq $ProjectName})
}