繁体   English   中英

Powershell构建步骤,失火了吗?

[英]Powershell build step, fire and forget?

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

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

由于我不希望脚本影响构建步骤,因此应该简单地触发并忘记脚本。 因此,我正在使用Start-Job 但似乎一旦完成该步骤,该过程就会被终止。 即使构建步骤已完成或构建过程已完成,是否仍可以保持过程寿命?

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

要简单地触发并忘记 ,请使用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 (可能需要更长的等待时间),但是这样的解决方案可能并不完全可靠 ,因为无法保证计时。
  • 由于您不打算监视远程执行,因此终止本地会话以及监视作业也无关紧要。

您何时希望脚本停止运行? 您可以使用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,因为脚本执行的操作不知道-如果不需要,请删除。

为什么不这样:

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)

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

有几种方法可以解决该问题,但最简单的方法可能是使用良好的ol'命令提示符来启动一个完全不基于原始脚本的独立新实例。 为此,可以将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启动脚本

如何在不显示窗口的情况下运行PowerShell脚本?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM