Powershell构建步骤,火灾和忘记?

时间:2018-02-27 20:24:20

标签: powershell tfs azure-devops jobs

我在使用TFS 2018的构建步骤中运行以下powershell命令。

Start-Job -ScriptBlock {
    Invoke-Command -FilePath \\MyServer\run.ps1 -ComputerName MyServer -ArgumentList arg1, arg2
}

由于我不希望脚本影响构建步骤,因此它应该只是触发并忘记脚本。因此我使用Start-Job。但似乎一旦完成该步骤,该过程就会被杀死。有没有办法维护进程生命周期,即使构建步骤已完成或构建过程已完成?

其他信息...... powershell脚本应该在远程服务器上运行。脚本本身会触发带参数的.exe。

4 个答案:

答案 0 :(得分:2)

要简单地触发并忘记,请使用Invoke-Command -AsJob调用脚本:

Invoke-Command -AsJob -FilePath \\MyServer\run.ps1 -ComputerName MyServer -Args arg1, arg2
Start-Sleep 1 # !! Seemingly, this is necessary, as @doorman has discovered.
  • 这应该远程启动脚本,异步,并在本地会话中创建一个作业来监控其执行。

    • 警告 :使用Start-Sleep - 可能还有更长的等待时间 - 似乎有必要在调用脚本退出之前创建远程进程,但是这样的解决方案可能不完全健壮,因为没有保证的时间。
  • 由于您不打算监控远程执行,本地会话终止 - 以及监控工作 - 应该无关紧要。

答案 1 :(得分:1)

您希望脚本何时停止运行?您可以使用do-while循环,然后找到符合您需求的<condition>

Start-Job -ScriptBlock {
    do{
        Invoke-Command -FilePath \\MyServer\run.ps1 -ComputerName MyServer -ArgumentList arg1, arg2
        Start-Sleep 2
    }while(<condition>)
}

或者,您可以使用条件$true,以便它永远执行。当您不再需要时,您将不得不在脚本中停止该作业。

$job = Start-Job -ScriptBlock {
    do{
        Invoke-Command -FilePath \\MyServer\run.ps1 -ComputerName MyServer -ArgumentList arg1, arg2
        Start-Sleep 2
    }while($true)
}

Stop-Job $job
Remove-Job $job

我添加了Start-Sleep 2因此它不会锁定你的CPU,因为不知道脚本在做什么 - 如果不需要则删除。

答案 2 :(得分:1)

为什么不这样:

Invoke-Command -Filepath \\MyServer\Run.ps1 -Computername MyServer -Argumentlist Arg1,Arg2 -AsJob
$JobCount = (get-job).Count
Do
{
    Start-Sleep -Seconds 1
    $totalJobCompleted = (get-job | Where-Object {$_.state -eq "Completed"} | Where-Object {$_.Command -like "NAMEOFCOMMAND*"}).count
}
Until($totalJobCompleted -ge $JobCount)

答案 3 :(得分:1)

@doorman - PowerShell本身就是一个单线程应用程序。几乎在所有情况下,这都是一个巨大的好处。即使强制多线程,您也可以看到子线程始终依赖于主线程。如果不是这种情况,那么创建内存泄漏将非常容易。这几乎总是一件好事,因为当您关闭主线程时,.Net将清理您可能忘记的所有其他线程。你碰巧碰到了这种行为对你的情况不利的情况。

有几种方法可以解决这个问题,但最简单的方法可能是使用良好的命令提示符启动一个完全不基于原始脚本的独立新实例。为此,您可以将invoke-expression与'cmd / c'结合使用。见下文:

invoke-expression 'cmd /c start powershell -NoProfile -windowstyle hidden -Command {
    $i = 0
    while ($true) {
        if($i -gt 30) {
            break
        }
        else {
            $i | Out-File C:\Temp\IndependentSessionTest.txt -Append
            Start-Sleep -Seconds 1
            $i++
        }
    }
}
'

这将启动一个新会话,运行您想要的脚本,不显示窗口,并且在脚本运行时不使用您的powershell配置文件。您将能够看到即使您终止原始PowerShell会话,这个会继续运行。关闭主PowerShell窗口后,您可以通过查看IndependentSessionTest.txt文件来验证这一点,并看到该文件不断获得更新的数字。

希望这能指出你正确的方向。

以下是一些源链接:

PowerShell launch script in new instance

How to run a PowerShell script without displaying a window?