如何在设定时间后从另一个脚本触发一个 PS 脚本,而不阻止执行

How to trigger one PS script from another after a set time, without blocking execution

假设我有一个文件 A.ps1 调用 B.ps1:

& "B.ps1"

我想要B.ps1的内容在N秒后运行,不阻塞A.ps1。在这种情况下,A.ps1 会立即完成,然后 B.ps1 的内容会在设定的时间后 运行。

如何实现?

上下文

我们正在利用 Release Management 通过 powershell 脚本部署构建。有时 RM 将我们需要的日志记录数据输出到 IR_ProcessAutoOutput 文件中——但这只会在 RM 完成后生成。所以我想在不阻塞的情况下将 "GetLogs" 脚本的执行推迟 ~20 秒,允许 RM 在此期间完成并生成 IR_ProcessAutoOutput。

使用 Start-Process 代替调用运算符。

Start-Process 'powershell.exe' -ArgumentList '-File', 'B.ps1'

如果您不希望进程 运行 在不同的 window 添加参数 -NoNewWindow.

您也可以 运行 第二个脚本作为 background job:

Start-Job -Scriptblock { & 'B.ps1' }

如果您希望 B.ps1A.ps1 已经终止后 开始,您需要创建计划任务。或者在B.ps1开头加个延时:

Start-Sleep -Seconds 20
...

正如 Ansgar 所建议的,Start-Process 的替代方法是安排任务。

确保任务在执行后自动删除

# A.ps1 doing its thing, and then:
$DelayInSeconds = 5
$SchTaskProperties = @{
    # Invoke powershell.exe -WindowStyle Hidden -File B.ps1
    Action   = New-ScheduledTaskAction -Id 0 -Execute powershell -Argument "-WindowStyle Hidden -File B.ps1" -WorkingDirectory 'C:\path\to\scripts'
    # Let it trigger in 5 seconds
    Trigger  = New-ScheduledTaskTrigger -At $([datetime]::Now.AddSeconds($DelayInSeconds)) -Once
    # Set task to be deleted after expiration, see below
    Settings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter (New-TimeSpan -Seconds 0)
    # Make up unique task name
    TaskName = "MyTask $([guid]::NewGuid())"
}
# Give the Trigger an EndBoundary (2 minutes later) to make sure it expires and is deleted
$SchTaskProperties['Trigger'].EndBoundary = [datetime]::UtcNow.AddMinutes(2).ToString('s') + 'Z'

# Register the task    
Register-ScheduledTask @SchTaskProperties |Out-Null
# Do whatever else A.ps1 needs to