如何在设定时间后从另一个脚本触发一个 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.ps1
在 A.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
假设我有一个文件 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.ps1
在 A.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