从命令行运行 PSAKE 脚本
我正在创建一个批处理文件来执行我的 psake 构建,同时与 teamcity 和来自 TFPT 的 TFS Powershell commandlet 集成,并提出以下问题:
@ECHO OFF
SET COMMAND_TO_EXECUTE=
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% "& {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% Import-Module '..\tools\psake\psake.psm1';
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% try
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% invoke-psake -framework '4.0' -taskList %1 -properties @{config='%2'}
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% catch
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% . ..\tools\psake\teamcity.ps1;
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% if(![string]::IsNullOrEmpty($env:TEAMCITY_VERSION))
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {TeamCity-ReportBuildStatus -status 'FAILURE' -text $_}
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% else
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {Write-Host ERROR: $_ -ForegroundColor RED};
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% exit $Error.Count;
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% finally {remove-module psake};
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };"
echo Build command is %COMMAND_TO_EXECUTE%
IF %PROCESSOR_ARCHITECTURE% == x86 (
powershell -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command %COMMAND_TO_EXECUTE%
) ELSE C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command %COMMAND_TO_EXECUTE%
当由于 Powershell 从未退出而发生错误时,我遇到了构建在 TeamCity 中未失败的问题非零退出代码。因此,我在上面的脚本中尝试执行的操作是捕获 Invoke-Psake 命令中的任何终止错误,向 teamcity 报告错误,并使用等于已发生错误数的非零代码退出进程。据我所知,剧本看起来不错。单独运行生成的命令似乎工作正常。但是,将其作为上面批处理文件的一部分运行,并将命令分配给 powershell 可执行文件的 -Command 参数,但会失败并出现错误:
一元后缺少表达式 运算符“-”
我不明白为什么会这样,特别是因为单独运行该命令似乎工作正常。任何人都可以阐明此事吗?这可能是某个地方的语法错误,但我无法弄清楚。
I'm creating a batch file to execute my psake builds while integrating with teamcity and the TFS Powershell commandlets from TFPT and have come up with the following:
@ECHO OFF
SET COMMAND_TO_EXECUTE=
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% "& {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% Import-Module '..\tools\psake\psake.psm1';
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% try
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% invoke-psake -framework '4.0' -taskList %1 -properties @{config='%2'}
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% catch
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% . ..\tools\psake\teamcity.ps1;
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% if(![string]::IsNullOrEmpty($env:TEAMCITY_VERSION))
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {TeamCity-ReportBuildStatus -status 'FAILURE' -text $_}
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% else
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% {Write-Host ERROR: $_ -ForegroundColor RED};
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% exit $Error.Count;
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% finally {remove-module psake};
SET COMMAND_TO_EXECUTE=%COMMAND_TO_EXECUTE% };"
echo Build command is %COMMAND_TO_EXECUTE%
IF %PROCESSOR_ARCHITECTURE% == x86 (
powershell -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command %COMMAND_TO_EXECUTE%
) ELSE C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command %COMMAND_TO_EXECUTE%
I was having problems with builds not failing in TeamCity when errors occur due to Powershell never exiting with a non-zero exit code. So what I'm attempting to do in the script above is to catch any terminating errors from the Invoke-Psake command, report the error to teamcity and exit the process with a non-zero code equal to the number of errors that had occurred. As far as I can tell the script seems fine. Running the resulting command on it's own seems to work fine. However running it as part of the batch file above with the command assigned to the -Command argument of the powershell executable it fails with the error:
Missing expression after unary
operator '-'
I can't see why that should be especially since running the command on it's own seems to work fine. Can anyone shed any light on the matter? It's probably a syntax error somewhere but I can't figure it out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
嗯,我认为你需要对转义字符施展一些魔法。
我从 cmd 执行的任何 powershell 调用都尝试保持如下格式 -
"powershell.exe -command '& {.C:\Temp\Example.ps1 -param1 hello}'"
您的复杂性来自多行 cmd您尝试构建的变量,变量展开时的每一行都将删除您应用的任何转义序列。
我为你搞乱了一些,但后来想...为什么你不直接创建带有脚本块的 .ps1 脚本,以保存任何令人讨厌的转义等。
所以 Invoke-Build.ps1 变成 -
参数($任务列表,$配置)
导入模块..\tools\psake\psake.psm1
尝试
{
invoke-psake -framework 4.0 -taskList $TaskList -properties @{config=$Config}
}
抓住
{
。 ..\tools\psake\teamcity.ps1;
if(![string]::IsNullOrEmpty($env:TEAMCITY_VERSION))
{
TeamCity-ReportBuildStatus -状态失败 -text $_
}
别的
{
写入主机错误:$_ -ForegroundColor RED
}
退出 $Error.Count
}
最后 {remove-module psake}
然后你可以从 cmd 获取脚本......
@echo OFF
SET COMMAND_TO_EXECUTE=Invoke-Build.ps1
echo Build 命令是“%COMMAND_TO_EXECUTE%”
IF %PROCESSOR_ARCHITECTURE% == x86 (
powershell -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -版本 "2.0" -NoProfile -ExecutionPolicy unrestricted -Command "& {.%COMMAND_TO_EXECUTE% -TaskList -Config}"
) 别的 (
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -版本 "2.0" -NoProfile -ExecutionPolicy unrestricted -Command "& {.%COMMAND_TO_EXECUTE% -TaskList -Config }”
Hmmm, think you need to do some magic with escape charaters.
Any invocation of powershell I do from cmd I try to keep the formation as follows -
"powershell.exe -command '& {. C:\Temp\Example.ps1 -param1 hello}'"
Your complication comes from the multi line cmd variable you are trying to build up, each line as the variable is expanded will remove any escape sequences you apply.
I messed around a bit for you, but then thought.... why dont you just create .ps1 script with your script block in, saves any nasty escaping etc.
So Invoke-Build.ps1 becomes -
Param($TaskList, $Config)
Import-Module ..\tools\psake\psake.psm1
try
{
invoke-psake -framework 4.0 -taskList $TaskList -properties @{config=$Config}
}
catch
{
. ..\tools\psake\teamcity.ps1;
if(![string]::IsNullOrEmpty($env:TEAMCITY_VERSION))
{
TeamCity-ReportBuildStatus -status FAILURE -text $_
}
else
{
Write-Host ERROR: $_ -ForegroundColor RED
}
exit $Error.Count
}
finally {remove-module psake}
Then you can just dot source the script from cmd......
@echo OFF
SET COMMAND_TO_EXECUTE=Invoke-Build.ps1
echo Build command is "%COMMAND_TO_EXECUTE%"
IF %PROCESSOR_ARCHITECTURE% == x86 (
powershell -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command "& {. %COMMAND_TO_EXECUTE% -TaskList -Config}"
) ELSE (
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -PSConsoleFile "%TFSPowerToolDir%tfshell.psc1" -Version "2.0" -NoProfile -ExecutionPolicy unrestricted -Command "& {. %COMMAND_TO_EXECUTE% -TaskList -Config}"