如何从TeamCity构建配置中设置PowerShell开关参数

时间:2014-10-13 12:35:43

标签: powershell teamcity parameter-passing

我有一个带有switch(boolean)参数的PowerShell脚本,我想从TeamCity构建步骤中调用它。

我希望根据TeamCity构建参数(配置参数)设置switch的值(true / false)。

所以,像这样: enter image description here

在PowerShell运行器构建步骤中: enter image description here

但上述方法无效。

我收到此错误

[14:27:01][Step 1/1] Cannot process argument transformation on parameter 'preRelease'. Cannot 
[14:27:01][Step 1/1] convert value "System.String" to type 
[14:27:01][Step 1/1] "System.Management.Automation.SwitchParameter". Boolean parameters accept only 
[14:27:01][Step 1/1] Boolean values and numbers, such as $True, $False, 1 or 0.

正如您所看到的,似乎PowerShell坚持将参数解释为字符串。

我尝试过编写脚本参数的许多变体。这些都不起作用:

-preRelease:%IncludePreRelease%
-preRelease:([boolean]%IncludePreRelease%)
-preRelease:([System.Convert]::ToBoolean(%IncludePreRelease%))

5 个答案:

答案 0 :(得分:5)

这是一个老问题,但如果您仍在寻找答案,我设法让它发挥作用。

主要技巧是你不应该像使用PowerShell一样在参数名和值之间实际使用冒号(我知道,令人困惑......)。

看起来TeamCity以不同的方式调用脚本并将参数作为字符串传递。

因此,在您的示例中,以下内容应该有效: -preRelease $%IncludePreRelease%

请注意,我在TeamCity变量前面添加了一个美元符号来更改" true"进入" $ true"

让我知道它是否适合你

谢谢!

答案 1 :(得分:5)

不,这仍然不会奏效。无论如何,TC似乎总是将值视为字符串。也许答案来自允许这种情况的TC版本,但最新版本没有。

没有冒号:

[16:18:37]Step 1/6: Migrate Up (Powershell)
[16:18:37][Step 1/6] PowerShell Executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
[16:18:37][Step 1/6] PowerShell arguments: [-NonInteractive, -ExecutionPolicy, ByPass, -File, C:\BuildAgent\work\f2797fec10821a01\data\Migration\MigrateUp.ps1, "data\change scripts", DB, xxxxxxx, sa, *******, -NoExec, $false]
[16:18:37][Step 1/6] C:\BuildAgent\work\f2797fec10821a01\data\Migration\MigrateUp.ps1 : A positional parameter cannot be found that accepts argument '$false'.

使用冒号:

 [16:18:37]Step 2/6: Migrate Up (Powershell)
 [16:18:37][Step 2/6] PowerShell Executable: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
 [16:18:37][Step 2/6] PowerShell arguments: [-NonInteractive, -ExecutionPolicy, ByPass, -File, C:\BuildAgent\work\f2797fec10821a01\data\Migration\MigrateUp.ps1, "data\change scripts", DB, xxxxxx, sa, *******, -NoExec:$false]
 [16:18:37][Step 2/6] C:\BuildAgent\work\f2797fec10821a01\data\Migration\MigrateUp.ps1 : Cannot process argument transformation on parameter 'NoExec'. Cannot convert value "System.String" to type "System.Management.Automation.SwitchParameter". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.

删除[switch]也不起作用,因为你给它的任何值都不会被视为布尔值 - 而是一个分配给布尔值的字符串 - 因此,所有布尔操作都将是{{1} }。

换句话说,您发送的任何内容都将如下所示:

  • 0 => ' 0'
  • 1 => ' 1'
  • $ false => ' $假'
  • $ true => ' $真'

(其中没有一个是== $true,但所有这些都等于$ true)

我不知道如何让TC接受布尔人! 我能做的最好的事情是假设参数是一个字符串,并在我的脚本内部使用System.Convert.ToBoolean()......

答案 2 :(得分:1)

根据Convert.ToBoolean的Microsoft .Net文档,传递给该方法的值必须为:

  

要成功进行转换,value参数必须相等   Boolean.TrueString,一个值为True的常量,   Boolean.FalseString,一个值为False的常量,或者必须是   空值。在将值与Boolean.TrueString进行比较时   Boolean.FalseString,该方法忽略大小写以及前导和   尾随空白。

如果您将TeamCity IncludePreRelease 变量值更改为" True "或" 错误" (没有引号)那么它应该正确转换。

答案 3 :(得分:0)

根据配置参数完全传递开关:

  1. 创建配置参数时,请选择“复选框”类型。
  2. 在“Checked value”中,输入“-preRelease”。
  3. 将“未选中的值”留空。
  4. 只需在您的脚本参数中添加“%IncludePreRelease%”即可。检查参数时,它将传递“-preRelease”(= true),如果不是,则省略(= false)。
  5. 这对我使用TeamCity 10.0.4。

答案 4 :(得分:0)

我知道这是一个迟到的答案,但我只是让一位同事在工作中偶然发现了同样的问题并找到了这个问题。

如果我们忘记TC一分钟,如果你想从cmd(而不是powershell控制台)执行相同的命令,那么确切的命令将是:

powershell.exe -File script.ps1 -preRelease

此命令将开关设置为True。这里重要的是命令首先由shell(cmd)解析。

因为shell是cmd,所以命令行中的powershell代码将不会被执行。

例如:

powershell -File script.ps1 -preRelase:"([System.Convert]::ToBoolean(%IncludePreRelease%))"

首次通过cmd解析后,它最终成为:

powershell -File script.ps1 -preRelase:"([System.Convert]::ToBoolean(True))"

所以preRelease标志被设置为整个字符串,它准确地为您提供

Cannot process argument transformation on parameter 'preRelease'. 
Cannot convert value "System.String" to type 
"System.Management.Automation.SwitchParameter"

基于documentation,使用-File时,您可以传递切换参数,也可以不传递。似乎没有办法传递TrueFalse值。

要使其正常工作,请从-File更改为-Command,如下所示:

powershell -Command .\script.ps1 -preRelease:$%IncludePreRelease%

现在,回到TeamCity。 Teamcity似乎不像上面那样支持-Comand。他们通过将整个脚本作为脚本块转储到命令行来支持它,这可能会导致非常有趣的错误。

解决方法是将Script更改为Source并在脚本内容中添加

.\script.ps1 -preRelease:$%env.IncludePreRelease%

Here is my configuration