Has anyone run into a problem when using PowerShell in a Jenkins Pipeline, where when you try to pull in an environmental variable (e.g., $env:CHANGE_ID
), it evaluates to something like this?
org.jenkinsci.plugins.workflow.cps.EnvActionImpl@1b69f5bb:VARIABLE_NAME
It looks like someone else was running into the same problem in this question, but I'm not sure that it was answered there (they show how to print all environment variables, but not how to get a specific one when toString
is not implemented):
Retrieve all properties of env in Jenkinsfile
My Jenkins pipeline file:
pipeline {
agent {
node {
label 'jenkins_managed_windows'
}
}
stages {
stage('SonarQube Analysis') {
steps {
powershell "dotnet sonarscanner begin /k:project-key /d:sonar.branch.name=$env:BRANCH_NAME"
}
}
stage('Build') {
steps {
powershell 'dotnet build'
}
}
stage('SonarQube End') {
steps {
powershell 'dotnet sonarscanner end'
}
}
}
}
The step with the environment variable gets run as:
dotnet sonarscanner begin /k:project-key /d:sonar.branch.name=org.jenkinsci.plugins.workflow.cps.EnvActionImpl@54ee3a8:BRANCH_NAME
powershell 'dotnet sonarscanner begin /k:project-key /d:sonar.branch.name=$env:BRANCH_NAME'
It doesn't even evaluate the environment variable at all, and just gets run as:
dotnet sonarscanner begin /k:project-key /d:sonar.branch.name=$env:BRANCH_NAME
The syntax forms $env:BRANCH_NAME
and the equivalent ${env:BRANCH_NAME}
are PowerShell constructs, which means that in order to pass them through to PowerShell in an interpolating Groovy string ("..."
), you must \
-escape the $
character to prevent Groovy from interpreting the construct up front:
powershell "dotnet sonarscanner begin ... /d:sonar.branch.name=\$env:BRANCH_NAME"
That said, given that your command contains no Groovy variables that need to be interpolated (it's safe and more robust to let PowerShell reference environment variables), you can simply use a literal Groovy string, '...'
, where $
chars. destined for PowerShell need no escaping:
powershell 'dotnet sonarscanner begin ... /d:sonar.branch.name=$env:BRANCH_NAME'
As for what you tried:
"... $env:BRANCH_NAME"
in an interpolating Groovy string causes Groovy to interpolate variable env
(since it is preceded by $
), and treat :BRANCH_NAME
as a literal.
Since env
refers to the object that contains all environment variables, what you're seeing is the (unhelpful) stringification of that object, which is the class name (org.jenkinsci.plugins.workflow.cps.EnvActionImpl
) followed by an instance-specific hash code (@54ee3a8
).
Using ${env.BRANCH_NAME}
would have worked - given that the value of environment variable BRANCH_NAME
can be accessed as a property of the env
object - but note that this means that Groovy interpolates the value up front and that PowerShell then only sees the resulting value.
In simple cases (environment-variable values without whitespace or special characters), "${env.BRANCH_NAME}"
(up-front interpolation by Groovy) and "\${env:BRANCH_NAME}"
(later interpretation by PowerShell) are interchangeable, but only the latter approach works robustly with all values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With