Search code examples
jenkinsjenkins-pipeline

How to update Env vars from jenkins Powershell script


Hello Trying to update jenkins Env variables from Powershell script written in stage

pipeline {
    agent { label 'master' }
    environment {
        def var1    = "default_value"
        def var2    = "default var 2"
    }
    stages {
        stage ('step-1') {
            steps {
                script { 
                    powershell (returnStdout: true, script: '''
                        ${env:var1} = "changed from powershell"
                        ${env:var2} = "var2 changed from powershell"
                    ''').trim()
                }
            }
        }
        stage ("step-2"){
            steps {
                echo var1
                echo var2
            }
        }
    }
}

I can access values but cannot change the same, Does Scope is limited to Powershell only?


Solution

  • By design, a subshell cannot modify the environment of its parent shell. Every powershell, sh, or bat step called within a Jenkinsfile spawns a new subshell to run the child processes. Therefore, any environment variable declared inside these steps are lost as soon as the child processes end and are not available to the pipeline Groovy script.

    One way to do this currently in a Jenkinsfile is to assign the stdout of your subshell to a variable in the Groovy script itself.

    script {
        env.var1 = powershell(returnStdout: true, script: '<single command>').trim()
    }
    

    Evidently, this approach has serious limitations as you can run only one command at a time and that too, only if it would return an appropriate output to be used as a variable.

    Another way is to write the values to a file and then read these values using Groovy script to set the environment variables downstream in your pipeline.

    Edit

    Based on your comment, if your stdout returns two distinct values as a string, you can try parsing them into separate values. For example:

    script {
        def output = powershell(returnStdout: true, script: '''
            <command1>
            <command2>
        ''')
        println(output)
        /*Prints:
        value1
        value2
        */
        env.var1 = output.tokenize('\n')[0].trim()  \\value1
        env.var2 = output.tokenize('\n')[1].trim()  \\value2
    }