Unable to update sensitive varibale in octopus using powershell script

Hi team,

we are trying to update a sensitive variable by using below PowerShell code but its not updating in the existing variable value rather it is adding one more empty plane value the variable please help us with the script to update the sensitive variable in the library variable set.
Add-Type -Path ‘C:\Program Files\Octopus\Newtonsoft.Json.dll’
Add-Type -Path ‘C:\Program Files\Octopus\Octopus.Client.dll’
$apikey = ‘xxxxxxxxxxx’ # Get this from your profile
$OctopusURL = ‘http://localhost:80/’ # Your server address
$header = @{ “X-Octopus-ApiKey” = $apikey }
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURL,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
$varaadtenet = “AAD Tenant”
$varenvname = “cbp02loaddev”
$varnewpwd = $password
$varname = “aadTenantPassword”
$variableSetName = $varaadtenet + " " + “-” + " " + $varenvname
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURL,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
$header = @{ “X-Octopus-ApiKey” = $apikey }
$VariableSets = (Invoke-WebRequest “$OctopusURL/api/libraryvariablesets?contentType=Variables” -UseBasicParsing -Headers $header).content | ConvertFrom-Json | select -ExpandProperty Items | ?{$_.name -eq $variableSetName}
#echo $VariableSets
$libraryVariableSetId = $VariableSets.Id
$libraryVariableSet = $repository.LibraryVariableSets.Get($libraryVariableSetId);
$variables = $repository.VariableSets.Get($libraryVariableSet.VariableSetId);

$variables.AddOrUpdateVariableValue($varname,$varnewpwd)

$repository.VariableSets.Modify($variables)

Write-Host “Variable Updated Successfully”

Hi @jsreekanth,

Thanks for getting in touch!

The step missing is to retrieve the specific variable after getting the variable set.
e.g.

        $libraryvariablesetId = $libraryvariableset.VariableSetId
        $variableset = $repository.VariableSets.Get($libraryvariablesetId)
        $variable = $variableset.Variables | ?{$_.name -eq $VariableToModify}

I’ve got a sample script that uses the octopus.client rather than a REST call to perform this:

#cls
function UpdateVarInProject {
    Param (
        [Parameter(Mandatory=$true)][string] $UserApiKey,
        [Parameter(Mandatory=$true)][string] $OctopusUrl,
        [Parameter(Mandatory=$true)][string] $VariableSetName,
        [Parameter(Mandatory=$true)][string] $VariableToModify,
        [Parameter(Mandatory=$true)][string] $VariableValue,
        [Parameter()][string] $EnvironmentScope,
        [Parameter()][string] $RoleScope,
        [Parameter()][string] $MachineScope,
        [Parameter()][string] $ActionScope
    )
    Process {
        Set-Location "C:\Program Files\Octopus Deploy\Tentacle"
        Add-Type -Path 'Newtonsoft.Json.dll'
        Add-Type -Path 'Octopus.Client.dll'
        $endpoint = New-Object Octopus.Client.OctopusServerEndpoint $OctopusUrl,$UserApiKey
        $repository = New-Object Octopus.Client.OctopusRepository $endpoint
        $libraryvariableset = $repository.libraryVariableSets.FindByName($libraryVariableSetName)
        $libraryvariablesetId = $libraryvariableset.VariableSetId
        $variableset = $repository.VariableSets.Get($libraryvariablesetId)
        $variable = $variableset.Variables | ?{$_.name -eq $VariableToModify}
        if ($variable) {
            $variable.Value = $VariableValue
            $Variable.IsSensitive = $false
        }
        else {
            $variable = new-object Octopus.Client.Model.VariableResource
            $variable.Name = $VariableToModify
            $variable.Value = $VariableValue
            $variableset.Variables.Add($variable)
        }
        try {
            if ($EnvironmentScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Environment, (New-Object Octopus.Client.Model.ScopeValue($EnvironmentScope)))        
            }
            if ($RoleScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Role, (New-Object Octopus.Client.Model.ScopeValue($RoleScope)))        
            }
            if ($MachineScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Machine, (New-Object Octopus.Client.Model.ScopeValue($MachineScope)))        
            }
            if ($ActionScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Action, (New-Object Octopus.Client.Model.ScopeValue($ActionScope)))        
            }
        }
        catch {}
        if ($repository.VariableSets.Modify($variableset)) {Write-Host "variabe $VariableToModify in $ProjectName successfully modified"}
    }
}
$OctopusUrl = "http://localhost"
$VarName = "Variable name" #Name of the variable to modify
$newvalue = "test35" # New value to set to the variable
$libraryVariableSetName = "Test"
$APIKey = "API-GZTUFPTUJYQH3CPH3ZYQ5G0W"
#Example
UpdateVarInProject -UserApiKey $APIKey -OctopusUrl $OctopusUrl -VariableSetName $libraryVariableSetName -VariableToModify $VarName -VariableValue $newvalue

I hope this helps, please let me know if you have any further questions.

Regards,
Paul

Hi team,
it looks like provided script is to update project varibale set but we are looking for updating the sensitive varibale in library varibale set could you please help us.
Thanks

Apologies, I modified the script from one that was intended to change project variables and didn’t change the function name.

If you test it out it should work for library variable sets.

Hi team,
can you please let us know which function name need to be changed for library variable sets.

Hi @jsreekanth,

Nothing needs to be changed, the script will work fine exactly as it is, if you want to give it a test.

The only part that is misleading is the function name that mentions the project. This has zero impact on the script function though.
e.g.

function UpdateVarInProject

Hi team,
can you please share and example script so that it will helpful for us.
Thanks

Hi @jsreekanth,

I’m not sure I understand, the script I provided is an example that will do exactly what you need.

Have you tried running it yet?

Hi Paul,
yes I tested it and script is failing with below error.

UpdateVarInProject : The property ‘Value’ cannot be found on this object.

May 29th 2020 16:01:49
Error
Verify that the property exists and can be set.

May 29th 2020 16:01:49
Error
At O:\Octopus-Sentience\Work\20200529103146-262110-29494\Script.ps1:145 char:1

May 29th 2020 16:01:49
Error

  • UpdateVarInProject -UserApiKey $APIKey -OctopusUrl $OctopusUrl -Varia …

May 29th 2020 16:01:49
Error

  • 
    
    

May 29th 2020 16:01:49
Error

  • CategoryInfo : InvalidOperation: (:slight_smile: [UpdateVarInProject], Runt

May 29th 2020 16:01:49
Error
imeException

May 29th 2020 16:01:49
Error

  • FullyQualifiedErrorId : PropertyAssignmentException,UpdateVarInProject

May 29th 2020 16:01:49
Error

May 29th 2020 16:01:49
Fatal
The remote script failed with exit code 1

May 29th 2020 16:01:49
Fatal
The action Check for mradmin password expiry on the Octopus Server failed

we are unable to update the sensitive variable in a library variable set.

It looks like you’re running the script from within an Octopus script step?
For the initial troubleshooting it would be easier to run the script directly in Powershell to see the error being output more clearly.

Also, are all of the required parameters filled?

$OctopusUrl = "http://localhost"
$VarName = "Variable name" #Name of the variable to modify
$newvalue = "test35" # New value to set to the variable
$libraryVariableSetName = "Test"
$APIKey = "API-GZTUFPTUJYQH3CPH3ZYQ5G0W"

Hi Paul,

I want to update the sensitive variable value in library variable set which i am unable to do it.
I am using the below code but which is adding one more empty value (with type plain text) to variable but it is not updating the existing value which is of sensitive type.

Add-Type -Path ‘C:\Program Files\Octopus\Newtonsoft.Json.dll’
Add-Type -Path ‘C:\Program Files\Octopus\Octopus.Client.dll’
$apikey = ‘xxxxxxxxxxx’ # Get this from your profile
$OctopusURL = ‘http://localhost:80/’ # Your server address
$header = @{ “X-Octopus-ApiKey” = $apikey }
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURL,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
$varaadtenet = “AAD Tenant”
$varenvname = “cbp02loaddev”
$varnewpwd = $password
$varname = “aadTenantPassword”
$variableSetName = $varaadtenet + " " + “-” + " " + $varenvname
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURL,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
$varaadtenet = “AAD Tenant”
$varenvname = “cbp02loaddev”
$varnewpwd = $password
$varname = “aadTenantPassword”
$variableSetName = $varaadtenet + " " + “-” + " " + $varenvname
$endpoint = new-object Octopus.Client.OctopusServerEndpoint $OctopusURL,$apikey
$repository = new-object Octopus.Client.OctopusRepository $endpoint
$header = @{ “X-Octopus-ApiKey” = $apikey }
$VariableSets = (Invoke-WebRequest “$OctopusURL/api/libraryvariablesets?contentType=Variables” -UseBasicParsing -Headers $header).content | ConvertFrom-Json | select -ExpandProperty Items | ?{$_.name -eq $variableSetName}
$libraryVariableSetId = $VariableSets.Id
$libraryVariableSet = $repository.LibraryVariableSets.Get($libraryVariableSetId);
$variables = $repository.VariableSets.Get($libraryVariableSet.VariableSetId);

$variables.AddOrUpdateVariableValue($varname,$varnewpwd)

$repository.VariableSets.Modify($variables)

Write-Host “Variable Updated Successfully”

Could you please let me know is it possible to update the sensitive variable in library variable set using Powershell script ?
If yes please help me.

Anusha

Hi Anusha,

In order to update a variable instead of adding a new one then you need to retrieve the details of that specific variable before performing the update.
e.g.

        $libraryvariablesetId = $libraryvariableset.VariableSetId
        $variableset = $repository.VariableSets.Get($libraryvariablesetId) #retrieve variable set
        $variable = $variableset.Variables | ?{$_.name -eq $VariableToModify} #retrieve specific variable by name

If you’re not able to factor that into your current script then an alternative would be to use this octopus.client script as a starting point and just remove the parts you don’t need.
You’ll need to update the parameters at the bottom of the script.

cls
function UpdateVarInVariableSet {
    Param (
        [Parameter(Mandatory=$true)][string] $UserApiKey,
        [Parameter(Mandatory=$true)][string] $OctopusUrl,
        [Parameter(Mandatory=$true)][string] $VariableSetName,
        [Parameter(Mandatory=$true)][string] $VariableToModify,
        [Parameter(Mandatory=$true)][string] $VariableValue,
        [Parameter()][string] $EnvironmentScope,
        [Parameter()][string] $RoleScope,
        [Parameter()][string] $MachineScope,
        [Parameter()][string] $ActionScope
    )
    Process {
        Set-Location "C:\Program Files\Octopus Deploy\Tentacle"
        Add-Type -Path 'Newtonsoft.Json.dll'
        Add-Type -Path 'Octopus.Client.dll'
        $endpoint = New-Object Octopus.Client.OctopusServerEndpoint $OctopusUrl,$UserApiKey
        $repository = New-Object Octopus.Client.OctopusRepository $endpoint
        $libraryvariableset = $repository.libraryVariableSets.FindByName($libraryVariableSetName)
        $libraryvariablesetId = $libraryvariableset.VariableSetId
        $variableset = $repository.VariableSets.Get($libraryvariablesetId)
        $variable = $variableset.Variables | ?{$_.name -eq $VariableToModify}
        if ($variable) {
            $variable.Value = $VariableValue
            $Variable.IsSensitive = $false
        }
        else {
            $variable = new-object Octopus.Client.Model.VariableResource
            $variable.Name = $VariableToModify
            $variable.Value = $VariableValue
            $variableset.Variables.Add($variable)
        }
        try {
            if ($EnvironmentScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Environment, (New-Object Octopus.Client.Model.ScopeValue($EnvironmentScope)))        
            }
            if ($RoleScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Role, (New-Object Octopus.Client.Model.ScopeValue($RoleScope)))        
            }
            if ($MachineScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Machine, (New-Object Octopus.Client.Model.ScopeValue($MachineScope)))        
            }
            if ($ActionScope){
                $variable.Scope.Add([Octopus.Client.Model.ScopeField]::Action, (New-Object Octopus.Client.Model.ScopeValue($ActionScope)))        
            }
        }
        catch {}
        if ($repository.VariableSets.Modify($variableset)) {Write-Host "variabe $VariableToModify in $ProjectName successfully modified"}
    }
}
$OctopusUrl = "http://localhost"
$VarName = "Variable name" #Name of the variable to modify
$newvalue = "test35" # New value to set to the variable
$libraryVariableSetName = "Test"
$APIKey = "API-GZTUFPTUJYQH3CPH3ZYQ5G0W"
#Example
UpdateVarInVariableSet -UserApiKey $APIKey -OctopusUrl $OctopusUrl -VariableSetName $libraryVariableSetName -VariableToModify $VarName -VariableValue $newvalue

As an additional question, what version of Octopus Server are you using?
I’ve just tested your original script and it is successfully updating the library set variable without creating a new one for me.

HI Paul,

The octopus server we are using of version 2019.9.12.

Hi guys,

I’ve tested your original script in 2019.9.12 and as far as I can tell it is working as expected.

I have this variable set configured:

I’ve updated the $password variable in your script several times now and run the script each time without seeing any new entries added.

Hi Paul,

Yes it is working for me now. Thanks for your help!!
But how can we see what has been updated in the value ? Is there any way we can see the value of a variable which is of sensitive type ?

Please help because script ran successfully but my deployment is failing hence i want to see what has been updated in the value.

Due to the sensitive nature of these variables, there isn’t any “easy” way of viewing them.
The only one I can think of would be to use the variable in a variable substitution on a file.

The only problem here is that variables are snapshotted when a release is created, so if you update a sensitive variable during a deployment it won’t actually take effect until the next release.

If this is the scenario that you require then output variables may be the solution for you. These are temporary variables that only last for the deployment.

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