I have one variable with about 20 different values. In my case these values are IP addresses for accessing production resources, and the variable is called prod_IPs. I am trying to use Powershell to export these values to a csv file.
While I can use the variable selection tool in the Powershell script window of the build step to select the variable itself, I am unsure how to iterate through each value for export to CSV. Something like “for each [value] in prod_IPs → append to CSV file”. What term could I use in the script to reference the value of a variable rather than the variable itself?
Greetings! For this, you could use something similar to
function Get-OctopusItems
{
# Define parameters
param(
$OctopusUri,
$ApiKey,
$SkipCount = 0
)
# Define working variables
$items = @()
$skipQueryString = ""
$headers = @{"X-Octopus-ApiKey"="$ApiKey"}
# Check to see if there there is already a querystring
if ($octopusUri.Contains("?"))
{
$skipQueryString = "&skip="
}
else
{
$skipQueryString = "?skip="
}
$skipQueryString += $SkipCount
# Get intial set
$resultSet = Invoke-RestMethod -Uri "$($OctopusUri)$skipQueryString" -Method GET -Headers $headers
# Check to see if it returned an item collection
if ($resultSet.Items)
{
# Store call results
$items += $resultSet.Items
# Check to see if resultset is bigger than page amount
if (($resultSet.Items.Count -gt 0) -and ($resultSet.Items.Count -eq $resultSet.ItemsPerPage))
{
# Increment skip count
$SkipCount += $resultSet.ItemsPerPage
# Recurse
$items += Get-OctopusItems -OctopusUri $OctopusUri -ApiKey $ApiKey -SkipCount $SkipCount
}
}
else
{
return $resultSet
}
# Return results
return $items
}
# Define working variables
$octopusURL = "https://YourServer"
$octopusAPIKey = "API-XXX"
$header = @{ "X-Octopus-ApiKey" = $octopusAPIKey }
$spaceName = "YourSpace"
$projectName = "YourProject"
$sourceEnvironmentName = "Production"
$destinationEnvironmentName = "Development"
# Get the space
$spaces = Get-OctopusItems -OctopusUri "$octopusURL/api/spaces" -ApiKey $octopusAPIKey
$space = $spaces | Where-Object {$_.Name -eq $spaceName}
# Get all projects
$projects = Get-OctopusItems -OctopusUri "$octopusURL/api/$($space.Id)/projects" -ApiKey $octopusAPIKey
# Filter project
$project = $projects | Where-Object {$_.Name -eq $projectName}
# Get variables
$variables = Get-OctopusItems -OctopusUri "$octopusURL/$($project.Links.Variables)" -ApiKey $octopusAPIKey
# Get environments
$environments = Get-OctopusItems -OctopusUri "$octopusURL/api/$($space.Id)/environments" -ApiKey $octopusAPIKey
# Get prod_IPs variables
$prod_IPs = $variables.Variables | Where-Object {$_.Name -eq "prod_IPs"}
# Loop through variables
foreach ($item in $prod_IPs)
{
# Save to csv
}
If you needed specifically the Production scoped ones, you could add something like this before the foreach
# Get environment Ids
$sourceEnvironmentId = ($environments | Where-Object {$_.Name -eq $sourceEnvironmentName}).Id
$destinationEnvironmentId = ($environments | Where-Object {$_.Name -eq $destinationEnvironmentName}).Id
# Get list of variables that have a production scope
$productionScopedVariables = $variables.Variables | Where-Object {$_.Scope.Environment -contains $sourceEnvironmentId}
Then iterate through the $productionScopedVariables list. The code above was lifted from another example, but it should be fairly close to what you’re trying to accomplish.
The $OctopusURI variable is what’s passed into the function and contains the $octopusURL as part of that value. The rest of the value for $OctopusURI is the specific endpoint you’re calling. In your case, $octopusURL would be https://octo.mydomain.com, but when calling the function, it would pass in https://octo.mydomain.com/api/spaces to get all spaces in your instance. Does that make sense?
Do you know how I could modify this script to refer to variable sets that have been linked to this project? I can only seem to return variable values that are established inside this specific project.
I hope you had a relaxing vacation. I spoke with Cory Reid over in the Slack channel and he helped me figure out a way to do the task. My variables were defined in a library variable set, not directly in the project itself. I could pull the local variable values but not any of the ones defined in the library set. Now I am able to do so. Thanks!