17

I am attempting to read an Azure DevOps secret variable from a Powershell pipeline script. The variable looks like this within Azure:

enter image description here

I've attempted to access the secret variable both as a param such as

[CmdletBinding()]
Param (
    $SecurePassword = $env:Password
)

and simply as an environment variable such as

$SecurePassword = $env:Password

Unfortunately the variable continues to appear null using either method.

enter image description here

I have no issue accessing non-secret variables. Any help would be greatly appreciated.

---------------------------------------- EDIT ----------------------------------------

I found documentation here stating that secrets are available to scripts within the pipeline if explicitly mapped in the environment section of the task.

enter image description here

I've updated my Powershell task and attempted to map the variable as both $(Password) and Password without any luck.

enter image description here

Mapping $(Password) as above reveals the string hidden behind asterisks.

Using $(Password) returns

4
  • 3
    Possible duplicate of VSTS secrets as environment variables Commented Jun 26, 2019 at 23:09
  • It would break security if you could do that - theoretically you could extract a bunch of passwords this way. Commented Jun 26, 2019 at 23:30
  • According to the information in your log, you should want to use ConvertTo-SecureString to decrypt encrypted environment variables, but this only applies to strings encrypted with powershell, and Secret variables in azure devops are encrypted at rest with a 2048-bit RSA key. They are Automatically masked out of any log output from the build or release. So I think you can't decrypt it in the log. Commented Jun 27, 2019 at 11:08
  • I've edited my question to include useful information I found here Commented Jun 27, 2019 at 13:53

2 Answers 2

10

We had a requirement to create a new project in Azure DevOps and needed to migrate all of the pipelines to the new project. Lo and behold, no one knew all of the secrets, and export / import doesn't accomplish this.

I wrote a script to output all environment variables into an "Extensions" tab next to the build summary. It's formatted and everything.

The key to outputting the secret is by altering the string by inserting the '<-eliminate->' phrase within the secret value and saving to a file. Once the file is created, we then remove all instances of the string '<-eliminate->', save the file, and there it sits as an extension page to the build summary.

I would like to somehow find All secrets dynamically, but for now manually defining the variable name does the trick.

I re-formatted for this post and removed proprietary info, please let me know if it's broken :)

function GetSecretLength ($secretVar){
     $i = 0;
     while($true){
          try { 
               $secretVar.substring(0,$i)|out-null 
          } catch { 
               break
          };
          $i++; 
     }
     if ($i -le 1) { return 1 }
     else { return $i-1 };
} 
function GetSecret($secret){
     $length = GetSecretLength($secret);
     if ($length -ge 2) {
        return $secret.substring(0,$length-1 )+"<-eliminate->"+$secret.substring($length-1,1)
    } elseif ($length -eq 1) {
        return $secret+"<-eliminate->"
    } else {
        return ""
    }
} 

$var = (gci env:*).GetEnumerator() | Sort-Object Name
$out = ""

Foreach ($v in $var) { $out = $out + "`t{0,-28} = {1,-28}`n" -f $v.Name, (GetSecret($v.Value)) }

$fileName = "$env:BUILD_ARTIFACTSTAGINGDIRECTORY\build-variables.md"
write-output "dump variables on $fileName"
set-content $fileName $out

write-output "##vso[task.addattachment type=Distributedtask.Core.Summary;name=Environment Variables;]$fileName"

((Get-Content -path $fileName -Raw) -replace '<-eliminate->', '') | Set-Content -Path $fileName

You have to add the secret variables that you want into the "Environment Variables" of the Powershell task: Environment Variables

You end up with this pretty tab: enter image description here

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

5 Comments

You are a bad guy - but that worked :D Thanks! As of now, there is no "Extensions" tab in that case, but a section under the summary.
@patman This no longer displays secrets, only the unmasked environment variables.
@Ostrava I guess they caught on to me lol
@patman - unfortunately!
It's so much easier to do: - task: CmdLine@2 inputs: script: cmd /K set
1

Why not just store the password in a keyvault as a secret? then there are azure commands for accessing the secret, and avoid all this. Heck, we generate random passwords, store them in keyvaults, then access the contents in the appropriate resource, without ever needing to expose the decrypted secret in a powershell command, like in an ARM template for an azure sql server database.

I know this doesn't solve your initial question, but it is a workaround that does work.

1 Comment

Would be great, if you could list the mentioned azure commands for accessing the secrets and/or pass a link to the documentation

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.