powershell tasks arguments are not passed correctly (Bug #297)


Added by Bart Maes about 4 years ago. Updated over 3 years ago.


Status:Feedback Start date:08/06/2013
Priority:High Due date:
Assignee:Ruben Willems % Done:

0%

Category:Task Spent time: -
Target version:1.9
Affected version:1.8.2

Description

In CruiseControl 1.8.2, a powershell task is executed with the command line:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -nologo -NoProfile -NonInteractive -file [script] [arguments]

In CruiseControl 1.6.7981.1, a powershell tasks was executed with the command line
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" [script] [arguments]

This breaks the way those parameters work and makes it nearly impossible to pass some types of parameters:
1) There is an exception whenever one of the arguments contains a "-" since powershell.exe thinks that it is another argument of powershell.exe. This results in an obscure exception:
Cannot process argument because the value of argument "name" is not valid. Change the value of the "name" argument and run the operation again.
2) It's no longer possible to pass boolean parameters ($true or $false) into a [bool] type. The exception says that it's impossible to convert a string into a boolean.
3) An array of strings is interpreted as 1 big string, cfr. comment at http://technet.microsoft.com/en-us/library/hh847736.aspx, where there is also a bit more information about this issue.

We are calling powershell for deployment and we encountered the first 2 issues with this command:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -nologo -NoProfile -NonInteractive -file "D:\tools\Scripts\deploy-xml.ps1" d:\Drops\RkdRequestLoggerNightly\1.0.0.119950\Acc\RkdRequestLoggerNightly.zip Do RkdRequestLogger Acc $null $null '2013-08-05' '14:07:08' '1.0.0.119950 - 2' 'http://bel-panamabuild.belux.conseur.org/server/local/project/RkdRequestLogger%20deploy%20to%20Acc/ViewProjectReport.aspx' '' $true no_ack

Because of this issue, we downgraded back to CruiseControl 1.6.7981.1 where we don't have it. I could imagine that a lot of other people could be affected by this...


History

Updated by Bart Maes about 4 years ago

The command line above was executed because of this build configuration:
<powershell>
<executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
<script>deploy.ps1</script>
<scriptsDirectory>D:\tools\Scripts</scriptsDirectory>
<buildArgs>$(deploymentPackage) $(projectDomain) $(projectName) $(environment) $(clients) $(parametersDirectory) '$[$CCNetBuildDate]' '$[$CCNetBuildTime]' '$[$CCNetLabel]' '$[$CCNetProjectUrl]' '$[$CCNetUser]' $[smoke_tests] $[ack_db_update]</buildArgs>
<buildTimeoutSeconds>1800</buildTimeoutSeconds>
</powershell>

Updated by Ruben Willems almost 4 years ago

  • Target version set to 1.8.5

Updated by Andreas Kromann almost 4 years ago

We are using powershell tasks with '-' in the script parameters on version 1.8.2 without issue.

Example:

<powershell>
  <script>Create-UnitTestEnvFile.ps1</script>
  <scriptsDirectory>$(scriptDir)</scriptsDirectory>
  <buildArgs>-environment "$(unittest-environment)" -serverdir "$(sourceDir)\$(Solution)\Debug\server\bin"</buildArgs>
  <buildTimeoutSeconds>0</buildTimeoutSeconds>
  <description>Sets the test env</description>
</powershell>

You can work around the problems with boolean and array args by calling powershell.exe in an exec-task instead:

<exec>
  <executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
  <buildArgs>-nologo -noprofile -noninteractive -command {c:\src\ps\testbool.ps1 -test $false -a 'one','two'}</buildArgs>
  <description>Testing</description>
</exec>

I think CCNet could fix this issue by simply using this format in the powershell tasks.

Updated by Ruben Willems almost 4 years ago

It seems to work in 1.8.4, can you re-check with that version?

The powershell configuration used :

1<powershell>
2    <script>args.ps1</script>
3    <scriptsDirectory>C:\CCNet\PowerShell</scriptsDirectory>
4    <buildArgs>-environment "blabla" -serverdir "somepath\Debug\server\bin" $[$CCNetBuildTime]</buildArgs>
5    <buildTimeoutSeconds>0</buildTimeoutSeconds>
6    <description>Sets the test env</description>
7</powershell>
8

The powershell script :

1Write-Host "Passed arguments : " 
2
3for ($i=0; $i -lt $args.length; $i++)
4{
5    Write-Host $Args[$i]
6}

output taken from build log file :

1<buildresults>
2  <message>Passed arguments : </message>
3  <message>-environment</message>
4  <message>blabla</message>
5  <message>-serverdir</message>
6  <message>somepath\Debug\server\bin</message>
7  <message>16:26:09</message>
8</buildresults>

should there be something setup differently for a better test scenario, let me know

  • Status changed from New to Feedback
  • Assignee set to Ruben Willems

Updated by Bart Maes almost 4 years ago

You are not using the right conditions to reproduce the bug.

A good test scenario is the one that was failing for us:

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -nologo -NoProfile -NonInteractive -file "D:\tools\Scripts\deploy-xml.ps1" d:\Drops\RkdRequestLoggerNightly\1.0.0.119950\Acc\RkdRequestLoggerNightly.zip Do RkdRequestLogger Acc $null $null '2013-08-05' '14:07:08' '1.0.0.119950 - 2' 'http://bel-panamabuild.belux.conseur.org/server/local/project/RkdRequestLogger%20deploy%20to%20Acc/ViewProjectReport.aspx' '' $true no_ack

Notice that:
  • there are dashes '-' inside of the values
  • we don't use named parameters but positional parameters
  • our deploy script is checking for parameter types and the value "$true" is no longer accepted as a [bool]. The first line of the deploy.ps1 contains the parameter definitions:
    param([string]$deploymentPackage = $(throw "deploymentPackage required."), [string]$projectDomain = $(throw "projectDomain required."), [string]$projectName = $(throw "projectName required."), [string]$environment = $(throw "environment required."), [string]$clients = $null, [string]$parametersDirectory = $null,[string]$projectfolder = $null,[string]$CCNetBuildDate=$null,[string]$CCNetBuildTime=$null,[string]$CCNetLabel=$null,[string]$CCNetProjectUrl=$null,[string]$CCNetUser=$null,[bool]$smoke_tests,[string]$ack_db_update,[bool]$verbose=$true)

This powershell commande line was generated by this CruiseControl configuration:
<powershell>
<executable>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe</executable>
<script>deploy.ps1</script>
<scriptsDirectory>D:\tools\Scripts</scriptsDirectory>
<buildArgs>$(deploymentPackage) $(projectDomain) $(projectName) $(environment) $(clients) $(parametersDirectory) '$[$CCNetBuildDate]' '$[$CCNetBuildTime]' '$[$CCNetLabel]' '$[$CCNetProjectUrl]' '$[$CCNetUser]' $[smoke_tests] $[ack_db_update]</buildArgs>
<buildTimeoutSeconds>1800</buildTimeoutSeconds>
</powershell>

I hope this helps to reproduce the bug and fix it...

Ruben Willems wrote:

It seems to work in 1.8.4, can you re-check with that version?

The powershell configuration used :

[...]

The powershell script :
[...]

output taken from build log file :
[...]

should there be something setup differently for a better test scenario, let me know

Updated by Ruben Willems almost 4 years ago

I used the following ccnet.config :

 1<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
 2  <cb:define deploymentPackage="d:\Drops\RkdRequestLoggerNightly\1.0.0.119950\Acc\RkdRequestLoggerNightly.zip" />
 3  <cb:define projectDomain="Some-Freaking-Domain" />
 4  <cb:define environment="TheEnvironment" />
 5  <cb:define projectName="TheprojectName" />
 6  <cb:define clients="TheClients" />
 7  <cb:define parametersDirectory="TheParametersDirectory" />
 8  <cb:define smoke_tests="TRUE" />
 9  <cb:define ack_db_update="ack_db_update" />
10
11  <project name="MyFirstProject" 
12           description="demoproject showing a small config">
13    <state type="state" directory="C:\CCNet\State" />
14    <artifactDirectory>C:\CCNet\BuildArtifacts\MyFirstProject</artifactDirectory>
15
16    <triggers />
17
18    <tasks>
19        <powershell>
20            <script>deploy.ps1</script>
21            <scriptsDirectory>C:\CCNet\PowerShell</scriptsDirectory>
22            <buildArgs>$(deploymentPackage) $(projectDomain) $(projectName) $(environment) $(clients) $(parametersDirectory) '$[$CCNetBuildDate]' '$[$CCNetBuildTime]' '$[$CCNetLabel]' '$[$CCNetProjectUrl]' '$[$CCNetUser]' $[smoke_tests] $[ack_db_update]</buildArgs>
23            <buildTimeoutSeconds>1800</buildTimeoutSeconds>
24        </powershell>
25    </tasks>
26
27    <publishers>
28      <xmllogger />
29    </publishers>
30
31  </project>
32</cruisecontrol>
33

the powershell script is the following :

 1param([string]$deploymentPackage = $(throw "deploymentPackage required."), [string]$projectDomain = $(throw "projectDomain required."), [string]$projectName = $(throw "projectName required."), [string]$environment = $(throw "environment required."), [string]$clients = $null, [string]$parametersDirectory = $null,[string]$projectfolder = $null,[string]$CCNetBuildDate=$null,[string]$CCNetBuildTime=$null,[string]$CCNetLabel=$null,[string]$CCNetProjectUrl=$null,[string]$CCNetUser=$null,[bool]$smoke_tests,[string]$ack_db_update,[bool]$verbose=$true)
 2
 3Write-Host "Deploying ...." 
 4Write-Host "Passed arguments : " 
 5
 6for ($i=0; $i -lt $args.length; $i++)
 7{
 8    Write-Host $Args[$i]
 9}

and the build results are as follows

1<buildresults>
2  <message>Deploying ....</message>
3  <message>Passed arguments : </message>
4</buildresults>
5

With that param statement at line 1, those arguments do not appear to be accessible anymore as comandline arguments,
but the powershell script does not fail!

Any idea what's wrong with the above test scenario?

Updated by Bart Maes almost 4 years ago

Ruben Willems wrote:

I used the following ccnet.config :

[...]

the powershell script is the following :

[...]

and the build results are as follows

[...]

With that param statement at line 1, those arguments do not appear to be accessible anymore as comandline arguments,
but the powershell script does not fail!

Any idea what's wrong with the above test scenario?

Hello Ruben,

1) If you define "smoke_tests" and "ack_db_update" as constants, you should refer to them using $(smoke_tests) and $(ack_db_update) in stead of $[smoke_tests] and $[ack_db_update].
2) The smoke_tests definition should be <cb:define smoke_tests="$true" /> in stead of <cb:define smoke_tests="TRUE" />
3) I don't know exactly why the arguments are not passed anymore, but the dashes in the projectDomain value might be part of the issue. Try using quotes in the build arguments around the projectDomain:
<buildArgs>$(deploymentPackage) '$(projectDomain)' $(projectName) $(environment) $(clients) $(parametersDirectory) '$[$CCNetBuildDate]' '$[$CCNetBuildTime]' '$[$CCNetLabel]' '$[$CCNetProjectUrl]' '$[$CCNetUser]' $[smoke_tests] $[ack_db_update]</buildArgs>

I think with these 3 changes you'll be able to reproduce the error...

Updated by Ruben Willems over 3 years ago

  • Target version changed from 1.8.5 to 1.9

Also available in: Atom PDF