簡體   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