Export all variables

Afternoon,

I’m trying to export all the variables preferably filtered by scope (environments)

I’ve had a look at this script but even if I looped through all the projects it requires a variable name to output the desired value

Is there a way to loop through every project finding the variables and filtering it via environment?

Thanks,

Dan

Hi Dan,

Thanks for getting in touch!

This should be doable with the caveat that it won’t return sensitive values.

The script you linked is a good starting point if you remove the additional variable name filtering and add any extra parts you need, such as returning the variable names and looping through all projects.

I modified the script to return all variable names and values scoped to the specified environment for the target project. Please don’t use this script as anything other than a guide. It is very rushed and hacked together.

e.g.



################ INPUT THESE VALUES ################
$OctopusServerUrl = "" #PUT YOUR SERVER LOCATION HERE. (e.g. http://localhost)
$ApiKey = "" #PUT YOUR API KEY HERE
$ProjectName = "" #PUT THE NAME OF THE PROJECT THAT HOUSES THE VARIABLES HERE
$SpaceName = ""         #PUT THE NAME OF THE SPACE THAT HAS THE PROJECT IN IT
$Environment = "" #PUT ENVIRONMENT NAME HERE

################ INPUT THESE VALUES #################

try {
    $headers = @{ "X-Octopus-ApiKey" = $ApiKey }
    $spaceList = Invoke-RestMethod "$OctopusServerUrl/api/spaces/all" -Headers $headers
    $space = $spaceList | Where-Object { $_.Name -eq $SpaceName }

    $url = "$OctopusServerUrl/api/$($space.Id)"
    $headers = @{ "X-Octopus-ApiKey" = $ApiKey }

    # Get Variable set
    $projectList = Invoke-RestMethod "$url/projects/all" -Headers $headers
    $project = $projectList | Where-Object { $_.Name -eq $ProjectName }
    $projectVariableSetId = $project.VariableSetId

    $variableSet = Invoke-RestMethod -Method "get" -Uri "$url/variables/$projectVariableSetId" -Headers $headers
    $Options = @{
        OctopusUrl = "$OctopusServerUrl/api/$($space.Id)"
        Headers    = @{ "X-Octopus-ApiKey" = $ApiKey }
        }

    $outputVariable = $null
    $envScopeValueSet = $False
    $foundEnvironmentWithinVariable = $false

    if ($Environment) {
        $environmentList = Invoke-RestMethod "$($Options.OctopusUrl)/environments/all" -Headers $Options.Headers
        $environment = $environmentList | Where-Object { $_.Name -eq $environment }
        $environmentId = $environment.Id
    }

    #Find matching varable by name
    $variables = $VariableSet.Variables # | Where-Object { $_.Name -eq $VariableName }

    #Loop through the variable
    ForEach ($variable in $variables) {

        #If there is a scoped environment and variable has not been set
        if ($variable.Scope.Environment -and !$envScopeValueSet) {
            #Iterate through the environments and see if our environment is one of them. Set flag to true if it is.
            ForEach ($element in $variable.Scope.Environment) {
                if ($element -eq $environmentId) {
                    $foundEnvironmentWithinVariable = $true
                }
            }
            #If we have found the environment earlier, set the value, set the flag that we've set the value.
            if ($foundEnvironmentWithinVariable) {
                $outputName = $variable.Name
                $outputValue = $variable.Value
                $outputVariable = "$outputName | $outputValue"
                write-host $outputVariable
                #$envScopeValueSet = $True
            }
        }
        
    }
}
catch {
    Write-Error $_.Exception.Message

    throw
}

Regards,
Paul

Thanks Paul,

I’ve given this a try on our dev instance, it just prints out all the variables regardless of environment. I’ve put PS into debug mode to run through and it’s strange because it seems to be working as written.

I’ve tried it with just want project and you initially wrote it and how I need it to be looping through each project. Still same issue, this is what I’ve amended below.

################ INPUT THESE VALUES ################
$OctopusServerUrl = "XXXXX" #PUT YOUR SERVER LOCATION HERE. (e.g. http://localhost)
$ApiKey = "XXXX" #PUT YOUR API KEY HERE
#$ProjectName = "XXXXXXX" #PUT THE NAME OF THE PROJECT THAT HOUSES THE VARIABLES HERE
$SpaceName = "Default"         #PUT THE NAME OF THE SPACE THAT HAS THE PROJECT IN IT
$Environment = "DEV" #PUT ENVIRONMENT NAME HERE

################ INPUT THESE VALUES #################

try {
    $headers = @{ "X-Octopus-ApiKey" = $ApiKey }
    $spaceList = Invoke-RestMethod "$OctopusServerUrl/api/spaces/all" -Headers $headers
    $space = $spaceList | Where-Object { $_.Name -eq $SpaceName }

    $url = "$OctopusServerUrl/api/$($space.Id)"
    $headers = @{ "X-Octopus-ApiKey" = $ApiKey }

    # Get Variable set
    $projectList = Invoke-RestMethod "$url/projects/all" -Headers $headers
    
    #$project = $projectList | Where-Object { $_.Name -eq $ProjectName }
    foreach($project in $projectlist){
    $projectVariableSetId = $project.VariableSetId

    $variableSet = Invoke-RestMethod -Method "get" -Uri "$url/variables/$projectVariableSetId" -Headers $headers
    $Options = @{
        OctopusUrl = "$OctopusServerUrl/api/$($space.Id)"
        Headers    = @{ "X-Octopus-ApiKey" = $ApiKey }
        }

    $outputVariable = $null
    $envScopeValueSet = $False
    $foundEnvironmentWithinVariable = $true

    if ($Environment) {
        $environmentList = Invoke-RestMethod "$($Options.OctopusUrl)/environments/all" -Headers $Options.Headers
        $environment = $environmentList | Where-Object { $_.Name -eq $environment }
        $environmentId = $environment.Id
    }

    #Find matching varable by name
    $variables = $VariableSet.Variables # | Where-Object { $_.Name -eq $VariableName }

    #Loop through the variable
    ForEach ($variable in $variables) {

        #If there is a scoped environment and variable has not been set
        if ($variable.Scope.Environment -and !$envScopeValueSet) {
            #Iterate through the environments and see if our environment is one of them. Set flag to true if it is.
            ForEach ($element in $variable.Scope.Environment) {
                if ($element -eq $environmentId) {
                    $foundEnvironmentWithinVariable = $true
                }
            }
            #If we have found the environment earlier, set the value, set the flag that we've set the value.
            if ($foundEnvironmentWithinVariable) {
                $outputName = $variable.Name
                $outputValue = $variable.Value
                $outputVariable = " $outputName , $outputValue" 
                write-host $outputVariable 
                outputVariable | Out-File variable.txt -Append
                #$envScopeValueSet = $True
            }
        }
        
    }
}
}
catch {
    Write-Error $_.Exception.Message

    throw
}

Just tried it with a different Environment, and debugged it doesn’t pull down the correct variable

$variable.scope doesn’t have an environment object only a machine one when I go through it so when doing the if statement it won’t followed by the foreach loop it doesn’t iterate correctly.

I was running it against a project with the following list of variables:

And with the environment field set to Dev it returns:

OctoBaseURL | https://octopus-operations.octopus.app
LongVariableTest | Password123456
PackageFeed | Feeds-1546

I’m unsure why you would be getting different behaviour. What version of Octopus Server are you running? I wouldn’t have thought we’d made changes in this area, but it is possible.

Hi Paul,

I’m running v2021.2 (Build 7727)

image

Do you get environment as an object above?

Thanks,

Dan

For the variables with env scoping I do:

image

Thanks Paul,

All sorted

1 Like

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