如何创建2个计划的任务,这些任务以一个小时的时间间隔运行,但不会重叠?

时间:2019-01-31 09:32:36

标签: powershell scheduled-tasks

我需要使用powershell创建两个计划任务,每个任务将运行一个powershell脚本。

应该在每天的08:00触发一次,然后每两个小时运行一次。因此,在10:00,12:00、14:00等。 另一个每天9点运行,每两个小时运行一次。所以在11:00,13:00、15:00等。

如果用户未登录,则登录后仍应立即触发任务。 可以说他登录9:35将触发这两个任务。它们如何不能同时运行?

我尝试为其中之一添加延迟,但是延迟可能为0

解决方案可以是:

  1. 当他们同时运行时,他们会检查这种情况是否存在,并检查其中一个出口。或者,
  2. 确保他们不会拦截的其他方法
   $taskAction1 = New-ScheduledTaskAction -Execute 'Powershell.exe' -argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $script1"
   $taskAction2 = New-ScheduledTaskAction -Execute 'Powershell.exe' -argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Bypass -File $script2"

   $taskSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -Hidden -DontStopIfGoingOnBatteries

   $taskTrigger = New-ScheduledTaskTrigger -AtLogOn
   $taskTriggerWithDelay = New-ScheduledTaskTrigger -AtLogOn -RandomDelay 00:15:00

   Register-ScheduledTask -User System -Action $taskAction1 -Trigger $TasKTrigger -TaskName "Task1" -RunLevel Highest -Settings $TaskSettings -f | Out-Null
   Register-ScheduledTask -User System -Action $taskAction2 -Trigger $taskTriggerWithDelay -TaskName "Task2" -RunLevel Highest -Settings $TaskSettings -f | Out-Null

   $trigger= Get-ScheduledTask -TaskName Task1
   $trigger.Triggers.repetition.Interval = "PT2H"
   $trigger.Triggers.repetition.duration = ""
   $trigger | Set-ScheduledTask | Out-Null

   $trigger= Get-ScheduledTask -TaskName Task2
   $trigger.Triggers.repetition.Interval = "PT2H"
   $trigger.Triggers.repetition.duration = ""
   $trigger | Set-ScheduledTask | Out-Null

1 个答案:

答案 0 :(得分:2)

问题与mutual exclusion有关,这是一个经过充分研究的问题。

一个简单的解决方案基于共享资源。任务启动时,它将尝试获取资源的互斥锁。如果这不可能,任务将等待并再次尝试直到授予超时或锁定。锁保持任务完成工作后,将在清理过程中释放锁。

简单的解决方案不能保证公平的调度,因此,如果需要公平性,请查找更多实现。

至于评论:不要依赖pid。在Windows中,可以重复使用进程ID。

为了进行快速演示,让我们像这样使用标记文件

function getlock() {
    $file = $null
    while($file -eq $null) {
        try { $file = [System.IO.File]::Open("c:\temp\flag.txt", "open", "read", "none") } catch {
            write-host "waiting..."
            start-sleep -seconds 2
        }
    }

    write-host "got lock!"
    start-sleep -seconds 5
    $file.close()
}

通过将函数加载到两个Powershell会话中并在几秒钟内调用它们来尝试一下。如果您在任务切换方面遇到问题,请增加5秒钟的睡眠时间。每个函数都将尝试获得对标志文件的排他锁。如果这不可能,则将引发异常。游戏后期的过程将休眠两秒钟,然后重试,直到第一个释放锁为止。有关文件共享模式的更多详细信息,请参见File.Open()

标记文件有问题,因此要获得更强大的IPC,请查看earlier an answer。它用于C#,但也可以针对Powershell进行调整。