Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-60423

Powershell fails when the script starts with 'CmdletBinding' attribut

    XMLWordPrintable

Details

    Description

      Hi, 

       

      Since upgrade to the latest version of PowerShell Plugin (1.4) a lot of my scripts does not work any more.

      Especially when inline or script files starts with the 'CmdletBinding' attribut.

      [workspace] $ powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\Users\ATHICS~1\AppData\Local\Temp\jenkins8862236051379677851.ps1

      Au caractŠre C:\Users\AthicService\AppData\Local\Temp\jenkins8862236051379677851.ps1:3 : 1

      + [CmdletBinding()]

      ~+ ~~~~~~~~~~~~~~~~~~

      Attribut inattendu ®ÿCmdletBindingÿ¯.

      Au caractŠre C:\Users\AthicService\AppData\Local\Temp\jenkins8862236051379677851.ps1:4 : 1

      + param([switch]$Elevated

      ~+ ~~~~~~

      Jeton inattendu ®ÿparamÿ¯ dans l'expression ou l'instruction.

          + CategoryInfo          : ParserError: ( [], ParentContainsErrorRecordException

          + FullyQualifiedErrorId : UnexpectedAttribute

       

      Build step 'PowerShell' marked build as failure

       

       

      As I have a lot of PS scripts like that, I have to downgrade to 1.3 version.

       

      Attachments

        Activity

          kahmeal Kamil Mackow added a comment -

          Seeing a similar issue in our scripts since updating to latest. Rolling back fixes the issue.

           

          $ powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\Users\SVC-JE~1\AppData\Local\Temp\2\jenkins310832792838059245.ps1
          At C:\Users\svc-jenkins_dev\AppData\Local\Temp\2\jenkins310832792838059245.ps1:3 char:79
          + ... lias("BuildConfiguration")][String] $build_configuration = "Release",
          +                                                                ~~~~~~~~~
          The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept 
          assignments, such as a variable or a property.
              + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
              + FullyQualifiedErrorId : InvalidLeftHandSide
           
          Build step 'PowerShell' marked build as failure

          Top of one of the offending scripts:

          Param(   
              [parameter()][Alias("BuildConfiguration")][String] $build_configuration = "Release",
              [parameter()][Alias("Test")][Switch] $run_tests,
              [parameter()][Alias("Analyze")][Switch] $run_analysis,
              [parameter()][Alias("Coverage")][Switch] $enforce_coverage,
              [parameter()][Alias("MinCoverage")][int] $min_coverage = 50
          )
          kahmeal Kamil Mackow added a comment - Seeing a similar issue in our scripts since updating to latest. Rolling back fixes the issue.   $ powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\Users\SVC-JE~1\AppData\Local\Temp\2\jenkins310832792838059245.ps1 At C:\Users\svc-jenkins_dev\AppData\Local\Temp\2\jenkins310832792838059245.ps1:3 char:79 + ... lias("BuildConfiguration")][String] $build_configuration = "Release", + ~~~~~~~~~ The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : InvalidLeftHandSide Build step 'PowerShell' marked build as failure Top of one of the offending scripts: Param( [parameter()][Alias("BuildConfiguration")][String] $build_configuration = "Release", [parameter()][Alias("Test")][Switch] $run_tests, [parameter()][Alias("Analyze")][Switch] $run_analysis, [parameter()][Alias("Coverage")][Switch] $enforce_coverage, [parameter()][Alias("MinCoverage")][int] $min_coverage = 50 )
          froque Filipe Roque added a comment -

          I'am able to reproduce the problem with the following script:
           

          param(
              [Parameter()][String] $Param1 = "this parameter #1",
              [Parameter()][String] $Param2 = "this parameter #2"
          )
          
          Write-Host $Param1
          Write-Host $Param2
          

          This runs fine, directly in the powershell:

          $ pwsh -NonInteractive -File Script.ps1 
          this parameter #1
          this parameter #2
          

          But, powershell version 1.4, prepends '$ErrorActionPreference="Stop"' or '$ErrorActionPreference="Continue"' to the script:

          $ErrorActionPreference="Continue"
          param(
              [Parameter()][String] $Param1 = "this parameter #1",
              [Parameter()][String] $Param2 = "this parameter #2"
          )
          
          Write-Host $Param1
          Write-Host $Param2
          
          $ pwsh -NonInteractive -File Script.ps1 
          ParserError: /home/froque/repos/jenkins-workspace/powershell-plugin/Script.ps1:3
          Line |
             3 |      [Parameter()][String] $Param1 = "this parameter #1",
               |                                      ~~~~~~~~~~~~~~~~~~~
               | The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.
          

           

          kahmeal soruk My question to you is: What's the point in defining these parameters, if there is no way to define its values? I fail to see how is this useful. A use case would be helpful.

          I could change the plugin only add '$ErrorActionPreference="Stop"' if configured as such or something else like it.

          froque Filipe Roque added a comment - I'am able to reproduce the problem with the following script:   param( [Parameter()][ String ] $Param1 = " this parameter #1" , [Parameter()][ String ] $Param2 = " this parameter #2" ) Write-Host $Param1 Write-Host $Param2 This runs fine, directly in the powershell: $ pwsh -NonInteractive -File Script.ps1 this parameter #1 this parameter #2 But, powershell version 1.4, prepends '$ErrorActionPreference="Stop"' or '$ErrorActionPreference="Continue"' to the script: $ErrorActionPreference= "Continue" param( [Parameter()][ String ] $Param1 = " this parameter #1" , [Parameter()][ String ] $Param2 = " this parameter #2" ) Write-Host $Param1 Write-Host $Param2 $ pwsh -NonInteractive -File Script.ps1 ParserError: /home/froque/repos/jenkins-workspace/powershell-plugin/Script.ps1:3 Line | 3 | [Parameter()][ String ] $Param1 = " this parameter #1" , | ~~~~~~~~~~~~~~~~~~~ | The assignment expression is not valid. The input to an assignment operator must be an object that is able to accept assignments, such as a variable or a property.   kahmeal soruk My question to you is: What's the point in defining these parameters, if there is no way to define its values? I fail to see how is this useful. A use case would be helpful. I could change the plugin only add '$ErrorActionPreference="Stop"' if configured as such or something else like it.

          Hi froque,

          I'm using the Standard PowerShell arguments, like -ErrorAction and -Verbose in my scripts that are set up before the call from Jenkins (as constants or as Jenkins Job parameter).

          For exemple, the -ErrorAction is sometimes "Stop" or "SilentlyContinue", depending of a given need.

          And a script might be called outside Jenkins.

          Param ( 
           [string]$workspace = $ENV:WORKSPACE,
           [string]$buildMode = $ENV:BUILD_MODE
          )
          $script = Join-Path $workspace "AthicAuthentication.$buildMode.ps1"
          $code = 0
          if (Test-Path -Path $script -ErrorAction SilentlyContinue) {
           $code = Invoke-Expression "$script" -ErrorAction Stop
          }
          exit $code

          What changed between 1.3 and 1.4 version that causes this issues ?

          soruk Aleksander Kasprzyk added a comment - Hi  froque , I'm using the Standard PowerShell arguments, like -ErrorAction and -Verbose in my scripts that are set up before the call from Jenkins (as constants or as Jenkins Job parameter). For exemple, the -ErrorAction is sometimes "Stop" or "SilentlyContinue", depending of a given need. And a script might be called outside Jenkins. Param ( [string]$workspace = $ENV:WORKSPACE, [string]$buildMode = $ENV:BUILD_MODE ) $script = Join-Path $workspace "AthicAuthentication.$buildMode.ps1" $code = 0 if (Test-Path -Path $script -ErrorAction SilentlyContinue) { $code = Invoke-Expression "$script" -ErrorAction Stop } exit $code What changed between 1.3 and 1.4 version that causes this issues ?
          kahmeal Kamil Mackow added a comment -

          Hi froque,

          We use these parameters as default values as these scripts are included in some of our build repositories and having commonly used defaults is a nice convenience for end users so they don't have to know every value but can override if they choose to without modifying the script itself.

          Does that answer the question?

          kahmeal Kamil Mackow added a comment - Hi froque , We use these parameters as default values as these scripts are included in some of our build repositories and having commonly used defaults is a nice convenience for end users so they don't have to know every value but can override if they choose to without modifying the script itself. Does that answer the question?
          owenmehegan Owen Mehegan added a comment -

          froque this plugin does not appear to have a default assignee in Jira. I assigned this to you because a CloudBees customer was impacted by this issue, and after I figured out the cause I saw that you did most of the recent work on it. If you will be maintaining the plugin going forward, let me know and I can make you the default assignee for new Jira issues so you will see them.

          owenmehegan Owen Mehegan added a comment - froque this plugin does not appear to have a default assignee in Jira. I assigned this to you because a CloudBees customer was impacted by this issue, and after I figured out the cause I saw that you did most of the recent work on it. If you will be maintaining the plugin going forward, let me know and I can make you the default assignee for new Jira issues so you will see them.
          froque Filipe Roque added a comment -

          owenmehegan I became a maintainer for this plugin a couple of months ago. yes, please make me the default assignee. If you could, please make me the default assignee for the plugin-usage-plugin as well, as I also became a maintainer for that plugin, last week.

          As for the issue, It is my understanding, that people are reusing existing scripts and pasting directly to the powershell plugin. A will take a look at it.

          froque Filipe Roque added a comment - owenmehegan I became a maintainer for this plugin a couple of months ago. yes, please make me the default assignee. If you could, please make me the default assignee for the plugin-usage-plugin as well, as I also became a maintainer for that plugin, last week. As for the issue, It is my understanding, that people are reusing existing scripts and pasting directly to the powershell plugin. A will take a look at it.
          owenmehegan Owen Mehegan added a comment -

          froque OK, I have made you the default assignee for those two plugins. 

          owenmehegan Owen Mehegan added a comment - froque OK, I have made you the default assignee for those two plugins. 
          sup3rmark_ Mark Corsillo added a comment - - edited

          Hello! Just wanted to fan the embers here a bit.

          There's a very valid use case for including a param() block in a Powershell script in Jenkins which is broken by this force-setting of ErrorActionPreference. We can set our parameters by tying them to environment variables (which are set as part of parameterized builds) but still retain the ability to run the script with parameters outside of Jenkins without having to maintain a separate script.

          One example of how we typically do this on my end:

          param ( 
            [string]$foo = if ($ENV:foo) {$ENV:foo} else {'default'},
            [string]$bar= if ($ENV:bar) {$ENV:bar} else {'default'}
          )

          By forcing the ErrorActionPreference with no option to disable that, the param block no longer works because the param block needs to be the first thing defined in a Powershell script.

           

          sup3rmark_ Mark Corsillo added a comment - - edited Hello! Just wanted to fan the embers here a bit. There's a very valid use case for including a param() block in a Powershell script in Jenkins which is broken by this force-setting of ErrorActionPreference. We can set our parameters by tying them to environment variables (which are set as part of parameterized builds) but still retain the ability to run the script with parameters outside of Jenkins without having to maintain a separate script. One example of how we typically do this on my end: param ( [string]$foo = if ($ENV:foo) {$ENV:foo} else { ' default ' }, [string]$bar= if ($ENV:bar) {$ENV:bar} else { ' default ' } ) By forcing the ErrorActionPreference with no option to disable that, the param block no longer works because the param block needs to be the first thing defined in a Powershell script.  
          sup3rmark_ Mark Corsillo added a comment -

          Submitted a PR to correct this issue. First time doing a PR for a real repo, so apologies if I've done anything incorrectly, but https://github.com/jenkinsci/powershell-plugin/pull/18

           

          froque mind taking a look when you get a chance? 

          sup3rmark_ Mark Corsillo added a comment - Submitted a PR to correct this issue. First time doing a PR for a real repo, so apologies if I've done anything incorrectly, but https://github.com/jenkinsci/powershell-plugin/pull/18   froque  mind taking a look when you get a chance? 
          froque Filipe Roque added a comment -

          sup3rmark_ That code excerpt does not work for me

          $ cat test.ps1
          param (
            [string]$foo = if ($ENV:foo) {$ENV:foo} else {'default'},
            [string]$bar= if ($ENV:bar) {$ENV:bar} else {'default'}
          )
          $ pwsh -File test.ps1 
          ParserError: (...)/test.ps1:2
          Line |
             2 |    [string]$foo = if ($ENV:foo) {$ENV:foo} else {'default'},
               |                  ~
               | Missing expression after '='.
          
          
          froque Filipe Roque added a comment - sup3rmark_ That code excerpt does not work for me $ cat test.ps1 param ( [string]$foo = if ($ENV:foo) {$ENV:foo} else { ' default ' }, [string]$bar= if ($ENV:bar) {$ENV:bar} else { ' default ' } ) $ pwsh -File test.ps1 ParserError: (...)/test.ps1:2 Line | 2 | [string]$foo = if ($ENV:foo) {$ENV:foo} else { ' default ' }, | ~ | Missing expression after '=' .
          sup3rmark_ Mark Corsillo added a comment - - edited

          froque sorry, you're right. should be:

          param (
            [string]$foo = $(if ($ENV:foo) {$ENV:foo} else {'default'}),
            [string]$bar = $(if ($ENV:bar) {$ENV:bar} else {'default'})
          )
          

           

          sup3rmark_ Mark Corsillo added a comment - - edited froque  sorry, you're right. should be: param ( [string]$foo = $( if ($ENV:foo) {$ENV:foo} else { ' default ' }), [string]$bar = $( if ($ENV:bar) {$ENV:bar} else { ' default ' }) )  

          People

            froque Filipe Roque
            soruk Aleksander Kasprzyk
            Votes:
            2 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated: