【问题标题】:Powershell Start-Process cmdlet not working from within a TFS Powershell scriptPowershell Start-Process cmdlet 在 TFS Powershell 脚本中不起作用
【发布时间】:2019-08-16 06:20:44
【问题描述】:

VS / TFS 2017 此帖子已更新以反映新信息

有 2 个 PowerShell 脚本:

p1.ps1
p2.ps1 

p1 在 TFS 构建过程中作为 PowerShell 任务执行。 p2 在 p1 中使用了两次。

使用1: p2是called from p1,表示p2被执行inline

使用2: p2 是launched from p1,意味着p1 执行p2 的fire and forget,即作为后台任务。

在 TFS 构建过程中,use 1 完全按预期工作,use 2 则不然。

在 p1 的末尾附近是以下 2 组不同的代码,它们已尝试用于 p2 的 fire and forget 执行:

$powershellArguments = "-file C:\conf\p2.ps1" , "refresh" , "C:\agent\_work\4\a\for-deploy\website\"
Start-Process powershell.exe -Argument $powershellArguments

And the 2nd methodology:

Start-Job -FilePath $baseFolder"p2.ps1" -ArgumentList "refresh", $sourceRoot

如果我在 Command Prompt PowerShell Window 中手动执行 p1,fire and forget p2 的执行将按预期与上述任一组代码一起发生。

但是当我运行构建并且 p1 以 a task within the build 执行时,p2 不会 fire and forget。同样,需要明确的是,在 TFS 构建中,use 1 inline 进程确实正确执行。

在脚本的开头,我嵌入了一些代码来编写一个小文本文件,以确认脚本至少正在启动,并且代码还写出接收到的参数以确保正确使用参数语法。当执行 p1 outside of the build environment 时,参数会正确传递给 p2。但是当 p1 作为 PowerShell 脚本 within the build 执行时,小文本文件并没有反映 p2 甚至以 fire and forget 模式启动。

原来 p1 和 p2 是同一个脚本,只是它们使用开关的执行方式略有不同。但是我复制了 p1 并将其命名为 p2 只是为了分隔 2 个脚本,结果是一样的。当 p1 正在执行 within the build 时,我无法让 p2 开始使用 Start-Process cmdletStart-Job cmdlet

我认为我一直很努力地缩小范围,似乎有一些关于从构建过程中的脚本中启动单独的脚本。

为什么会这样?有没有办法解决这个问题?

我确实想知道它是否与基本脚本策略有关,例如在尝试运行包含-executionpolicy remotesigned 的 PowerShell 脚本的批处理文件中。这可能吗?

【问题讨论】:

  • 使用脚本的完整路径有帮助吗?通常 PowerShell.exe 在 System32 文件夹中启动,它会尝试从那里执行脚本。
  • 我认为我们在这里有异步帖子。我现在有了完整的路径,但仍然存在问题,但正如我刚刚在上面评论的那样,我的问题似乎与参数传递有关。仍在努力,但会留下帖子,直到我解决它...
  • 参数传递和完整路径寻址确认良好,如上面修改后的帖子中所述。
  • 我猜当 p1 构建任务完成时 p2 也终止了,尝试将 Start-Sleep 放在 p1 的末尾(运行 p2 需要多少时间)并检查 p2 结果。
  • 我会尝试将睡眠作为一种锻炼,因为这将有助于诊断正在发生的事情,但遗憾的是,从长远来看它并不能解决我的问题。我试图尽可能缩短构建时间。 p2 执行是使用耗时的 FTP 命令刷新目标数据。我试图将刷新作为一项单独的任务启动,以便构建可以提前退出。没有必要仅仅为了数据更新而延迟构建完成。但这是对可能发生的事情的一个很好的洞察。很难说,因为构建执行大部分是隐藏在视图中的。日志对此并没有真正的帮助。

标签: powershell tfs tfsbuild start-process


【解决方案1】:

cmets 中的@Shayik-Abramczyk 是正确的。当您使用Start-Job 时,如果 PowerShell 会话终止,任何通过Start-Job 启动的执行作业也会终止。

有几种方法可以实现您想要的。这取决于您的特定情况。您可以使用Register-ScheduledJobStart-Process。我想你可能想要Start-Process

Start-Process PowerShell.exe -ArgumentList "-NonInteractive", "-NoLogo", "-File", ".\$(Join-Path $baseFolder p2.ps1)", 
 "refresh", "$sourceRoot" -NoNewWindow

HTH。

【讨论】:

  • 当我重新访问它并返回结果时会尝试这个。谢谢!
  • 我更新了我的答案,为 PowerShell 进程添加了一些选项——否则,可能会导致打开一个窗口,这可能是不可取的。
猜你喜欢
  • 2012-12-28
  • 1970-01-01
  • 2018-06-15
  • 2014-02-28
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 2013-12-19
  • 1970-01-01
相关资源
最近更新 更多