繁体   English   中英

Powershell:具有每日触发和重复间隔的计划任务

[英]Powershell: Scheduled Task with Daily Trigger and Repetition Interval

我似乎无法弄清楚如何创建一个每天触发并每 30 分钟重复一次的新计划任务。 我一直在兜圈子。

下面的所有内容都适用于设置我想要的任务,但只触发一次。

#Credentials to run task as
$username = "$env:USERDOMAIN\$env:USERNAME" #current user
$password = "notmypass"

#Location of Scripts:
$psscript = "C:\test\test.ps1"
$Sourcedir ="C:\testsource\"
$destdir = "C:\testdest\"
$archivepassword = "notmypass"


####### Create New Scheduled Task
$action = New-ScheduledTaskAction -Execute "Powershell" -Argument "-WindowStyle Hidden `"$psscript `'$sourcedir`' `'$destdir`' `'$archivepassword`'`""
$trigger = New-ScheduledTaskTrigger -Once -At 7am -RepetitionDuration  (New-TimeSpan -Days 1)  -RepetitionInterval  (New-TimeSpan -Minutes 30)
$settings = New-ScheduledTaskSettingsSet -Hidden -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable
$ST = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask EncryptSyncTEST -InputObject $ST -User $username -Password $password

如果我改变-Once-Daily我失去了-RepetitionInterval标志。 如果我在注册后回来将任务更新为每天,它会清除重复触发器。

这不是一种不常见的调度方法,并且可以通过任务调度程序 UI 轻松应用。 我觉得这可能很简单,但我很想念它。

任何帮助表示赞赏。

编辑:解决重复的问题。 Powershell v3 New-JobTrigger daily with重复一文中的问题也在问同样的问题。 但正如我之前评论的那样,没有一个答案可以解决问题。 标记的答案完全符合我在此处已有的功能,它使用 -Once 触发器设置任务,然后将其更新为每 5 分钟重复一次,持续 1 天。 第一天之后,该任务将永远不会再次触发。 它没有解决每天通过重复和持续时间触发任务直到下一次触发的问题。

该帖子上的其他三个答案也没有解决这个问题。 我不知道为什么它被标记为已回答,因为它不正确。 在发布这个问题之前,我充分研究了这些回复。 随着那篇文章变老并被标记为已回答,我创建了这个问题。

注意:我找到了一种解决方法,但不是很好。 目前,使用 powershell 定义自定义触发器的最简单方法似乎是操作计划任务 XML 并使用Register-ScheduledTask直接导入它

虽然用于计划任务触发器的 PowerShell 接口是有限的,但事实证明,如果将RepetitionDuration设置为[System.TimeSpan]::MaxValue ,则会导致持续时间“无限期”。

$trigger = New-ScheduledTaskTrigger `
    -Once `
    -At (Get-Date) `
    -RepetitionInterval (New-TimeSpan -Minutes 5) `
    -RepetitionDuration ([System.TimeSpan]::MaxValue)

在 Windows Server 2012 R2 (PowerShell 4.0) 上测试

这是一种在 Powershell(我的机器上为 v5,YMMV)中创建计划任务的方法,该任务将每天上午 12点开始,并在一天其余时间每小时重复一次 因此它将无限期地运行。 我相信这是一种优于将-RepetitionDuration设置为([timespan]::MaxValue) -RepetitionDuration ([timespan]::MaxValue)正如我之前评论的那样,因为触发器将在任务计划程序中显示为:

每天上午 12:00 - 触发后,每 30 分钟重复一次,持续 1 天。

任务注册的日期出现在触发器中,而不是作为使用-Once -At 12am结果的方法,将触发器创建为简单的-Daily -At 12am ,注册任务然后访问任务触发器的一些进一步属性财产;

$action = New-ScheduledTaskAction -Execute <YOUR ACTION HERE>
$trigger = New-ScheduledTaskTrigger -Daily -At 12am
$task = Register-ScheduledTask -TaskName "MyTask" -Trigger $trigger -Action $action
$task.Triggers.Repetition.Duration = "P1D" //Repeat for a duration of one day
$task.Triggers.Repetition.Interval = "PT30M" //Repeat every 30 minutes, use PT1H for every hour
$task | Set-ScheduledTask
//At this point the Task Scheduler will have the desirable description of the trigger.

我相信一定有更好的方法,但这是我目前的解决方法。

我用我想要的触发器创建了一个任务,然后抓取了它生成的 XML。

下面我正在创建任务,然后为该新任务提取 XML,替换我的触发器,然后取消注册任务并使用更新的 XML 重新注册它。

从长远来看,我可能只会使用完整的 XML 文件来完成任务并根据需要替换字符串,但这目前有效。

#Credentials to run task as
$username = "$env:USERDOMAIN\$env:USERNAME" #current user
$password = "notmypass"

#Location of Scripts:
$psscript = "C:\test\test.ps1"
$Sourcedir ="C:\testsource\"
$destdir = "C:\testdest\"
$archivepassword = "notmypass"

####### Create New Scheduled Task
$action = New-ScheduledTaskAction -Execute "Powershell" -Argument "-WindowStyle Hidden '$EncryptSync' '$sourcedir' '$destdir' '$archivepassword'"
$trigger = New-ScheduledTaskTrigger -Once -At 7am -RepetitionDuration  (New-TimeSpan -Days 1)  -RepetitionInterval  (New-TimeSpan -Minutes 30)
$settings = New-ScheduledTaskSettingsSet -Hidden -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -RunOnlyIfNetworkAvailable
$ST = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask "EncryptSyncTEST" -InputObject $ST -User $username -Password $password


[xml]$EncryptSyncST = Export-ScheduledTask "EncryptSyncTEST"
$UpdatedXML = [xml]'<CalendarTrigger xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"><Repetition><Interval>PT30M</Interval><Duration>P1D</Duration><StopAtDurationEnd>false</StopAtDurationEnd></Repetition><StartBoundary>2013-11-18T07:07:15</StartBoundary><Enabled>true</Enabled><ScheduleByDay><DaysInterval>1</DaysInterval></ScheduleByDay></CalendarTrigger>'
$EncryptSyncST.Task.Triggers.InnerXml = $UpdatedXML.InnerXML

Unregister-ScheduledTask "EncryptSyncTEST" -Confirm:$false
Register-ScheduledTask "EncryptSyncTEST" -Xml $EncryptSyncST.OuterXml -User $username -Password $password

创建基础触发器:

$t1 = New-ScheduledTaskTrigger -Daily -At 01:00

创建二级触发器:

$t2 = New-ScheduledTaskTrigger -Once -RepetitionInterval (New-TimeSpan -Minutes 15) -RepetitionDuration (New-TimeSpan -Hours 23 -Minutes 55)

从次要对象中取出重复对象,并将其插入基本触发器中:

$t1.Repetition = $t2.Repetition

鲍勃是你的叔叔:

New-ScheduledTask -Trigger $t1 -Action ...

我找到的最简单的方法是使用 schtasks.exe。 请参阅https://msdn.microsoft.com/en-us/library/windows/desktop/bb736357%28v=vs.85%29.aspx 上的完整文档

schtasks.exe /CREATE /SC DAILY /MO 1 /TN 'task name' /TR 'powershell.exe C:\test.ps1' /ST 07:00 /RI 30 /DU 24:00

这将创建一个每天运行的任务,每 30 分钟重复一次,持续时间为 1 天。

另一种方法是创建多个触发器,如下所示:

$startTimes     = @("12:30am","6am","9am","12pm","3pm","6pm")
$triggers = @()
foreach ( $startTime in $startTimes )
{
    $trigger = New-ScheduledTaskTrigger -Daily -At $startTime -RandomDelay (New-TimeSpan -Minutes $jitter)
    $triggers += $trigger
}

如果你想在 Windows 10 上有一个无限的任务持续时间,只需使用这个(不要指定 -RepetitionDuration)

$action = New-ScheduledTaskAction -Execute (Resolve-Path '.\main.exe')
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1)

Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "GettingDataFromDB" -Description "Dump of new data every hour"

https://stackoverflow.com/a/54674840/9673214 @SteinIP 解决方案对我有用,稍加修改

在“创建辅助触发器”部分添加了与“创建基本触发器”部分具有相同值的“-At”参数。

创建基础触发器

$t1 = New-ScheduledTaskTrigger -Daily -At 01:00

创建二级触发器:

$t2 = New-ScheduledTaskTrigger -Once -RepetitionInterval (New-TimeSpan -Minutes 15) -RepetitionDuration (New-TimeSpan -Hours 23 -Minutes 55) -At 01:00

施展魔法:

$t1.Repetition = $t2.Repetition

New-ScheduledTask -Trigger $t1 -Action ...

老问题,我不确定是否需要 powershell cmdlet。 但我只使用 schtasks。

如果您想每 15 分钟运行一次:

schtasks /f /create /tn taskname `
    /tr "powershell c:\job.ps1" /ru system `
    /sc minute /mo 15 /sd 01/01/2001 /st 00:00

这将在 2001 年 1 月 1 日午夜“触发”,每 15 分钟运行一次。 所以如果你今天创建它,它只会在下一个事件间隔运行。

如果您希望它每天都“触发”,您可以这样做:

schtasks /f /create /tn taskname `
    /tr "powershell c:\job.ps1" /ru system `
    /sc daily /sd 01/01/2001 /st 10:00 /du 12:14 /ri 15

这将在 2001 年 1 月 1 日上午 10 点“触发”,每 15 分钟运行一次,持续 12 小时 14 分钟。 所以如果你今天启动它,它只会在下一个事件间隔运行。

我通常像顶部一样运行“每 15 分钟”,而像底部一样运行“每天 x 次”。 因此,如果我需要在上午 10 点和下午 2 点运行某些内容,我只需将第二个的 /du 更改为 5 小时,将 /ri 更改为 4。然后它每 4 小时重复一次,但仅持续 5 小时。 从技术上讲,你可以把它放在 4:01 持续时间,但为了安全起见,我通常给它一个小时。

我曾经使用 task.xml 方法并且在第二个场景中遇到了非常困难的时间,直到我在导出的 task.xml 中注意到它基本上只有下面这样的内容。

<Triggers>
    <CalendarTrigger>
      <Repetition>
        <Interval>PT3H</Interval>
        <Duration>PT15H</Duration>
        <StopAtDurationEnd>false</StopAtDurationEnd>
      </Repetition>
      <StartBoundary>2017-11-27T05:45:00</StartBoundary>
      <ExecutionTimeLimit>PT10M</ExecutionTimeLimit>
      <Enabled>true</Enabled>
      <ScheduleByDay>
        <DaysInterval>1</DaysInterval>
      </ScheduleByDay>
    </CalendarTrigger>
  </Triggers>

这是针对在 5:45 到 7:45 之间每 3 小时运行一次的作业。 所以我只是将间隔和持续时间输入到每日计划命令中,它运行良好。 我只是使用旧日期进行标准化。 我猜你总是可以在今天开始它,然后它会起作用。

要在远程服务器上运行它,我使用这样的东西:

$sb = { param($p); schtasks /f /create /tn `"$p`" /tr `"powershell c:\jobs\$p\job.ps1`" /ru system /sc daily /sd 01/01/2001 /st 06:00 /du 10:00 /ri (8*60) } }
Invoke-Command -ComputerName "server1" -ScriptBlock $sb -ArgumentList "job1"

这是另一种变体,似乎对这个老栗子很有效,但不如其他一些解决方案复杂。 它已经在 Server 2012 R2、Server 2016 和 Server 2019 上进行了测试,每个操作系统上都有默认的 PS 版本。 “合并”触发器在 2012 年对我不起作用。没有打扰其他人。

步骤很简单:

  1. 先用基本计划创建计划任务
  2. 从新任务中提取详细信息
  3. 修改触发重复/持续时间
  4. 使用修改后的版本更新现有任务

该示例包含每天每小时重复一次的每日任务(我已将其设置为 23 小时以使日期/时间语法更清晰一些)。 持续时间和间隔使用相同的时间跨度格式。

# create the basic task trigger and scheduled task
$trigger = New-ScheduledTaskTrigger -Daily -At 15:55
$Settings = New-ScheduledTaskSettingsSet –StartWhenAvailable
Register-ScheduledTask -TaskName $TaskName -Trigger $Trigger -Action $Action -Setting $Settings -User $User

# Get the registered task parameters
$task = Get-Scheduledtask $TaskName

# Update the trigger parameters to the repetition intervals
$task.Triggers[0].Repetition.Duration = "P0DT23H0M0S"
$task.Triggers[0].Repetition.Interval = "P0DT1H0M0S"

# Commit the changes to the existing task
Set-ScheduledTask $task

请注意,如果您的任务有多个触发器 - 尽管如果您有重复间隔这会很不寻常 - 您需要修改需要重复的触发器。 该示例只有一个触发器,因此我们只选择触发器列表中的第一个(也是唯一一个)成员 - $task.Triggers[0]

时间跨度是 ISO 8601 格式 - 它是一个没有空格的字符串。 所需的数值在时间指定之前(例如, 1H表示一小时,而不是H1 )。 该字符串必须包含列出的所有时间名称,用0代替任何空值。 开头的P (“句点”)表示它是持续时间而不是时间戳。

P(eriod)0D(ays)T(ime)0H(ours)0M(inutes)0S(econds)
P0DT1H0M0S  = 0 days, 1 hours, 0 minutes, 0 seconds
P0DT0H15M30S = 0 days, 0 hours, 15 minutes, 30 seconds

如果要更改任务的开始时间,可以使用类似的方法来修改触发器。 这适用于-Once-Daily任务。

$task = Get-ScheduledTask $taskname
$d = ([DateTime]::now).tostring("s")  # 2021-11-30T17:39:31
$task.Triggers[0].StartBoundary = $d
Set-ScheduledTask $task

在 Windows 10 中工作

Set-ExecutionPolicy RemoteSigned

$action=New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument '‪C:\Users\hp\Anaconda3\python.exe ‪C:\Users\hp\Desktop\py.py'
$trigger = New-ScheduledTaskTrigger `
    -Once `
    -At (Get-Date) `
    -RepetitionInterval (New-TimeSpan -Minutes 15) `
    -RepetitionDuration (New-TimeSpan -Days (365 * 20))
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "ts2" -Description "tsspeech2" 

暂无
暂无

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

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