1

I have a requirement to load the variables inside a variable group into an azure keyvault. We do not want to link the variable group to the keyvault in order to be able to close the keyvault external network access.

So I started developing a powershell script that lists the variable group variables using az cli devops extension and stores it into a powershell var.

Then I iterate for each var and try to build the var name in Azure Devops format $(var) so I can use it with Set-AzKeyVaultSecret.

The problem: It seems the variable name has to be hardcoded for the Azure Devops pipeline to be able to convert it to it's real value.

Example:

$pipelineVarEnc = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$('variablename')"))

Does not work:

        $Name = $var.Name
        $command = '$pipelineVarEnc = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$(' + $Name + ')"))'
        Invoke-command $command

Anyone knows how to bypass this issue?

2
  • 1
    Correct - the AzDO macro expansion happens before the script is parsed and executed by the PowerShell runner - so you can't make AzDO dynamically resolve it in the middle of the script Commented Jun 28, 2022 at 14:36
  • @MathiasR.Jessen that makes sense. However I have also stored the commands in a separate script and invoked the script from another Azure Devops task and had the same result. It cannot recognize the value of $Name so although I'm passing $(bananas) it complains about bananas not being a command. Is there any known way to populate a keyvault from a variablegroup using a pipeline without hardcoding variable names? Commented Jun 28, 2022 at 14:46

1 Answer 1

1

Refer to the following PowerShell script:

$token = "PAT"

$url="https://dev.azure.com/{ORG}/{PROJECT}/_apis/distributedtask/variablegroups/{VariableGroupID}?api-version=6.0-preview.2"

$token = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes(":$($token)"))

$response = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Basic $token"} -Method Get  -ContentType application/json


ForEach ($variable in $response.variables)

{
  #echo $variable

  
  $variablenames =  $variable | Get-Member | Where {$_.MemberType -like 'NoteProperty'} | Select-Object  -Property name

  ForEach ($name in $variablenames.name)
  {
     $varaiblename = $name

     $variablevalue =  $variable.$name.value

     echo  $varaiblename
     echo  $variablevalue

     $Secret = ConvertTo-SecureString -String '$variablevalue' -AsPlainText -Force
     Set-AzKeyVaultSecret -VaultName 'xx' -Name '$varaiblename' -SecretValue $Secret

  }
     
}

In the PowerShell Script, it uses the Rest API: Variablegroups - Get to get all variables in the Variable Group.

We can modify the response format to get all variable names.

Finally, we can get the variable value based on the variable name.

In this case, we can iterate over all variable names and values without hardcoding.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the script sample Kevin. Do you know if this works if the variables in the variable group are set to secret?
If the variable is secret, we are not able to get the value of the variable via Rest API or Azure DevOps CLI.
Then how are we able? Only by passing as hardcoded script parameter to the powershell task? That seems very limited.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.