Powershell v4。创建将过期和删除的远程任务调度器任务集

时间:2023-02-06 00:35:42

I am trying to create a task that essentially reboots the server but the task is put there by a remote server running a check to see if a reboot is needed. I am stuck trying to add an expiration so it deletes itself but can't find where to put that setting or what it is. It has to do with an end boundry or something and this setting -DeleteExpiredTaskAfter but don't know what value to put in.

我正在尝试创建一个任务,该任务实际上是重新引导服务器,但是任务是由一个远程服务器执行的,运行一个检查以查看是否需要重新启动。我正试图添加一个过期,这样它就会删除自己,但却找不到该把设置放在哪里,或者它是什么。它与末端的边界或其他东西有关,这个设置-DeleteExpiredTaskAfter但不知道输入什么值。

$dc = "server2reboot"
$taskname = "Reboot $DC"
$taskpath  = "PendingReboots"
$CimSession = New-CimSession -ComputerName $dc -Credential $credentials -Authentication Negotiate

Function Create-AndRegisterRebootTask{
 Param ($taskname, $taskpath)
 $action = New-ScheduledTaskAction -Execute '#shutdown.exe -r -f -t 0"'
 $trigger =  New-ScheduledTaskTrigger -once -At ("$nextsundaydate 3:00") -RandomDelay 03:00:00 
 Register-ScheduledTask -CimSession $cimsession -RunLevel Highest  -Action $action -Trigger $trigger -TaskName $taskname -Description "Server Reboot" -TaskPath $taskpath -Force
 }



Function Create-NewRebootTaskSettings{
 Param ($taskname, $taskpath)
 $settings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter "PT0S" -compatability "win8" -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit "PT1H" -RestartCount 3
 Set-ScheduledTask -CimSession $cimsession -TaskName $taskname -Settings $settings -TaskPath $taskpath
 }

Create-AndRegisterRebootTask -taskname $taskname -taskpath $taskpath 
Create-NewRebootTaskSettings -taskname $taskname -taskpath $taskpath 

Set-ScheduledTask : The task XML is missing a required element or attribute.
(48,4):EndBoundary:
At line:5 char:2
+  Set-ScheduledTask -CimSession $cimsession -TaskName $taskname -Settings $settin ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (PS_ScheduledTask:Root/Microsoft/...S_ScheduledTask) [Set-ScheduledTask], CimException
    + FullyQualifiedErrorId : HRESULT 0x80041319,Set-ScheduledTask

3 个解决方案

#1


3  

This error is caused by a bug introduced in the Task Scheduler back in Vista. Read more here "The task XML is missing a required element or attribute" error when you use the /z switch together with the Schtasks command in Windows Vista

这个错误是由Vista中任务调度程序中引入的一个错误引起的。当您在Windows Vista中使用/z开关和Schtasks命令时,在这里阅读更多的“任务XML缺少必需的元素或属性”错误。

The work around is to create a task compatible with pre-Windows Vista platforms, if you want to use the -DeleteExpiredTaskAfter parameter.

如果您想使用-DeleteExpiredTaskAfter参数,则需要创建一个与windows Vista前平台兼容的任务。

This is

这是

-Compatibility V1

Or in your code

或者在你的代码

$settings = New-ScheduledTaskSettingsSet -Compatibility V1 -DeleteExpiredTaskAfter 00:00:01 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 01:00:00 -RestartCount 3

There are other things to look out for when setting a scheduled task to expire.

在设置预定任务时,还有其他事情需要注意。

Valid values.

有效值。

There is only a limited number of values that are valid a parameter "-DeleteExpiredTaskAfter". These are Imediately (PT0S), 30 days (P30D), 90 days (P90D), 180 days (P180D) and 365 days (P365D).

参数“-DeleteExpiredTaskAfter”有效的值数量是有限的。它们分别是Imediately (PT0S), 30天(P30D), 90天(P90D), 180天(P180D)和365天(P365D)。

Other Prerequisites

其他先决条件

Before a task can be set to expire there has to be a trigger with an expiration time (EndBoundary) set.

在将任务设置为过期之前,必须有一个设置了过期时间(EndBoundary)的触发器。

This is where I'm stuck at the moment, because new PS4.0 cmdlets don't seem to cater for this.

这就是我目前的困境,因为新的PS4.0 cmdlet似乎不能满足这个需求。

In the meantime here is an "old school" way of setting up a scheduled task directly via Scheduler Service COM interface.

与此同时,这里有一种“老学校”的方式,通过调度器服务COM接口直接设置预定的任务。

$server = "...."
$domain = $server
$user = "...."
$password = "...."

$ExecuteTime = (Get-Date).AddDays(1)
$ExpireTime = $ExecuteTime.AddMinutes(1)

$taskname = "Reboot $server"
$taskpath  = "PendingReboots"
$taskdesc = "Server Reboot"

$ShedService = new-object -comobject "Schedule.Service"
$ShedService.Connect($server, $user, $domain, $password)

$Task = $ShedService.NewTask(0)
$Task.RegistrationInfo.Description = "$taskdesc"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$Task.Settings.DeleteExpiredTaskAfter = "PT0S"
$Task.Settings.ExecutionTimeLimit = "PT1H"
$Task.Settings.StopIfGoingOnBatteries = $false
$Task.Settings.RestartCount = 3

$trigger = $task.triggers.Create(1) # Creates a "One time" trigger
#    TASK_TRIGGER_EVENT     0
#    TASK_TRIGGER_TIME      1
#    TASK_TRIGGER_DAILY     2
#    TASK_TRIGGER_WEEKLY    3
#    TASK_TRIGGER_MONTHLY   4
#    TASK_TRIGGER_MONTHLYDOW    5
#    TASK_TRIGGER_IDLE      6
#    TASK_TRIGGER_REGISTRATION  7
#    TASK_TRIGGER_BOOT      8
#    TASK_TRIGGER_LOGON     9
#    TASK_TRIGGER_SESSION_STATE_CHANGE  11

$trigger.StartBoundary = $ExecuteTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.EndBoundary = $ExpireTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.Enabled = $true

$Action = $Task.Actions.Create(0)
$action.Path = "shutdown.exe"
$action.Arguments = " -r -f -t 0"

Try {$taskFolder = $ShedService.GetFolder("\$taskpath")}
catch {$taskFolder = $ShedService.GetFolder("\").CreateFolder("$taskpath")}

$result = $taskFolder.RegisterTaskDefinition("$TaskName",$Task,6,"System",$null,5)

#2


1  

With some help from Craig Duff, here is how you can create a task that is deleted after being run without the compatibility flag and using the PS4.0 cmdlets:

在Craig Duff的帮助下,以下是如何创建一个在没有兼容性标志的情况下运行并使用PS4.0 cmdlet后被删除的任务:

$run = (Get-Date).AddMinutes(2) # Two minutes from now
Register-ScheduledTask -TaskName "MyTask"  -User "Domain\User" -InputObject (
  (
    New-ScheduledTask -Action (
      New-ScheduledTaskAction -Execute "C:\path\to\your.exe" -Argument (
        "many" + 
        "arguments " +
        """with quotes"" "
      )
    ) -Trigger (
      New-ScheduledTaskTrigger -Once -At ($run.TimeOfDay.ToString("hh\:mm")) # As a "TimeOfDay" to get 24Hr format
    ) -Settings (
      New-ScheduledTaskSettingsSet  -DeleteExpiredTaskAfter 00:00:01 # Delete one second after trigger expires
    ) 
  ) | %{ $_.Triggers[0].EndBoundary = $run.AddMinutes(60).ToString('s') ; $_ } # Run through a pipe to set the end boundary of the trigger
)

The thing is that the trigger must have an EndBoundary defined so that the task can be deleted. The New-ScheduledTaskTrigger cmdlet doesn't have a parameter to define it. The trick is then to create the task and register it in two different steps, with a step in between to define the End Boundary of the trigger. Obviously if your task has more than one trigger, you would need to set the End Boundary for each.

问题是,触发器必须定义一个EndBoundary,以便能够删除任务。新的scheduledtasktrigger cmdlet没有定义它的参数。技巧是创建任务并在两个不同的步骤中注册它,中间的步骤定义触发器的结束边界。显然,如果您的任务有多个触发器,您需要为每个触发器设置结束边界。

This specific example creates a task that will run c:\path\to\your.exe once called MyTask two minutes into the future, running with credentials Domain\User. The trigger will expire an hour after the execution start (just so someone could verify if it was run from the scheduled tasks window, instead of browsing through the windows logs), and the task will be deleted one second after that.

此特定示例创建一个将运行c:\path\到\您的。exe在未来两分钟内调用MyTask,使用凭据域\用户运行。该触发器将在执行开始后一个小时过期(只是为了让某人验证它是否从计划任务窗口运行,而不是浏览windows日志),任务将在执行开始后一秒钟被删除。

#3


0  

This will create the task and then update it with the expires and delete values allowing the EndBoundary value to be set. The below example sets both the expiration and deletion to 30 days from value of $run.

这将创建任务,然后使用expires和delete值对其进行更新,允许设置EndBoundary的值。

Make sure to set the run time to at least one min in the future to allow the task to be update before it runs.

确保将运行时间设置为至少一个min,以便在任务运行之前进行更新。

$run = (Get-Date).AddMinutes(1);
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument 'C:\temp\install-<whateveryouneed>.ps1' -WorkingDirectory 'C:\temp'
$trigger = New-ScheduledTaskTrigger -Once -At $run

$settings = New-ScheduledTaskSettingsSet -Compatibility Win8
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Install 
from scheduled task" -Description "Installs stuff from a scheduled task as system" -User "system" -Settings $settings

$task = (Get-ScheduledTask -TaskName "Install 
from scheduled task")
$task.Triggers[0].EndBoundary = $run.AddDays(30).ToString('s')
$task.Settings.DeleteExpiredTaskAfter = "P30D"
Set-ScheduledTask -InputObject $task

#1


3  

This error is caused by a bug introduced in the Task Scheduler back in Vista. Read more here "The task XML is missing a required element or attribute" error when you use the /z switch together with the Schtasks command in Windows Vista

这个错误是由Vista中任务调度程序中引入的一个错误引起的。当您在Windows Vista中使用/z开关和Schtasks命令时,在这里阅读更多的“任务XML缺少必需的元素或属性”错误。

The work around is to create a task compatible with pre-Windows Vista platforms, if you want to use the -DeleteExpiredTaskAfter parameter.

如果您想使用-DeleteExpiredTaskAfter参数,则需要创建一个与windows Vista前平台兼容的任务。

This is

这是

-Compatibility V1

Or in your code

或者在你的代码

$settings = New-ScheduledTaskSettingsSet -Compatibility V1 -DeleteExpiredTaskAfter 00:00:01 -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit 01:00:00 -RestartCount 3

There are other things to look out for when setting a scheduled task to expire.

在设置预定任务时,还有其他事情需要注意。

Valid values.

有效值。

There is only a limited number of values that are valid a parameter "-DeleteExpiredTaskAfter". These are Imediately (PT0S), 30 days (P30D), 90 days (P90D), 180 days (P180D) and 365 days (P365D).

参数“-DeleteExpiredTaskAfter”有效的值数量是有限的。它们分别是Imediately (PT0S), 30天(P30D), 90天(P90D), 180天(P180D)和365天(P365D)。

Other Prerequisites

其他先决条件

Before a task can be set to expire there has to be a trigger with an expiration time (EndBoundary) set.

在将任务设置为过期之前,必须有一个设置了过期时间(EndBoundary)的触发器。

This is where I'm stuck at the moment, because new PS4.0 cmdlets don't seem to cater for this.

这就是我目前的困境,因为新的PS4.0 cmdlet似乎不能满足这个需求。

In the meantime here is an "old school" way of setting up a scheduled task directly via Scheduler Service COM interface.

与此同时,这里有一种“老学校”的方式,通过调度器服务COM接口直接设置预定的任务。

$server = "...."
$domain = $server
$user = "...."
$password = "...."

$ExecuteTime = (Get-Date).AddDays(1)
$ExpireTime = $ExecuteTime.AddMinutes(1)

$taskname = "Reboot $server"
$taskpath  = "PendingReboots"
$taskdesc = "Server Reboot"

$ShedService = new-object -comobject "Schedule.Service"
$ShedService.Connect($server, $user, $domain, $password)

$Task = $ShedService.NewTask(0)
$Task.RegistrationInfo.Description = "$taskdesc"
$Task.Settings.Enabled = $true
$Task.Settings.AllowDemandStart = $true
$Task.Settings.DeleteExpiredTaskAfter = "PT0S"
$Task.Settings.ExecutionTimeLimit = "PT1H"
$Task.Settings.StopIfGoingOnBatteries = $false
$Task.Settings.RestartCount = 3

$trigger = $task.triggers.Create(1) # Creates a "One time" trigger
#    TASK_TRIGGER_EVENT     0
#    TASK_TRIGGER_TIME      1
#    TASK_TRIGGER_DAILY     2
#    TASK_TRIGGER_WEEKLY    3
#    TASK_TRIGGER_MONTHLY   4
#    TASK_TRIGGER_MONTHLYDOW    5
#    TASK_TRIGGER_IDLE      6
#    TASK_TRIGGER_REGISTRATION  7
#    TASK_TRIGGER_BOOT      8
#    TASK_TRIGGER_LOGON     9
#    TASK_TRIGGER_SESSION_STATE_CHANGE  11

$trigger.StartBoundary = $ExecuteTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.EndBoundary = $ExpireTime.ToString("yyyy-MM-dd'T'HH:mm:ss")
$trigger.Enabled = $true

$Action = $Task.Actions.Create(0)
$action.Path = "shutdown.exe"
$action.Arguments = " -r -f -t 0"

Try {$taskFolder = $ShedService.GetFolder("\$taskpath")}
catch {$taskFolder = $ShedService.GetFolder("\").CreateFolder("$taskpath")}

$result = $taskFolder.RegisterTaskDefinition("$TaskName",$Task,6,"System",$null,5)

#2


1  

With some help from Craig Duff, here is how you can create a task that is deleted after being run without the compatibility flag and using the PS4.0 cmdlets:

在Craig Duff的帮助下,以下是如何创建一个在没有兼容性标志的情况下运行并使用PS4.0 cmdlet后被删除的任务:

$run = (Get-Date).AddMinutes(2) # Two minutes from now
Register-ScheduledTask -TaskName "MyTask"  -User "Domain\User" -InputObject (
  (
    New-ScheduledTask -Action (
      New-ScheduledTaskAction -Execute "C:\path\to\your.exe" -Argument (
        "many" + 
        "arguments " +
        """with quotes"" "
      )
    ) -Trigger (
      New-ScheduledTaskTrigger -Once -At ($run.TimeOfDay.ToString("hh\:mm")) # As a "TimeOfDay" to get 24Hr format
    ) -Settings (
      New-ScheduledTaskSettingsSet  -DeleteExpiredTaskAfter 00:00:01 # Delete one second after trigger expires
    ) 
  ) | %{ $_.Triggers[0].EndBoundary = $run.AddMinutes(60).ToString('s') ; $_ } # Run through a pipe to set the end boundary of the trigger
)

The thing is that the trigger must have an EndBoundary defined so that the task can be deleted. The New-ScheduledTaskTrigger cmdlet doesn't have a parameter to define it. The trick is then to create the task and register it in two different steps, with a step in between to define the End Boundary of the trigger. Obviously if your task has more than one trigger, you would need to set the End Boundary for each.

问题是,触发器必须定义一个EndBoundary,以便能够删除任务。新的scheduledtasktrigger cmdlet没有定义它的参数。技巧是创建任务并在两个不同的步骤中注册它,中间的步骤定义触发器的结束边界。显然,如果您的任务有多个触发器,您需要为每个触发器设置结束边界。

This specific example creates a task that will run c:\path\to\your.exe once called MyTask two minutes into the future, running with credentials Domain\User. The trigger will expire an hour after the execution start (just so someone could verify if it was run from the scheduled tasks window, instead of browsing through the windows logs), and the task will be deleted one second after that.

此特定示例创建一个将运行c:\path\到\您的。exe在未来两分钟内调用MyTask,使用凭据域\用户运行。该触发器将在执行开始后一个小时过期(只是为了让某人验证它是否从计划任务窗口运行,而不是浏览windows日志),任务将在执行开始后一秒钟被删除。

#3


0  

This will create the task and then update it with the expires and delete values allowing the EndBoundary value to be set. The below example sets both the expiration and deletion to 30 days from value of $run.

这将创建任务,然后使用expires和delete值对其进行更新,允许设置EndBoundary的值。

Make sure to set the run time to at least one min in the future to allow the task to be update before it runs.

确保将运行时间设置为至少一个min,以便在任务运行之前进行更新。

$run = (Get-Date).AddMinutes(1);
$action = New-ScheduledTaskAction -Execute 'Powershell.exe' -Argument 'C:\temp\install-<whateveryouneed>.ps1' -WorkingDirectory 'C:\temp'
$trigger = New-ScheduledTaskTrigger -Once -At $run

$settings = New-ScheduledTaskSettingsSet -Compatibility Win8
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Install 
from scheduled task" -Description "Installs stuff from a scheduled task as system" -User "system" -Settings $settings

$task = (Get-ScheduledTask -TaskName "Install 
from scheduled task")
$task.Triggers[0].EndBoundary = $run.AddDays(30).ToString('s')
$task.Settings.DeleteExpiredTaskAfter = "P30D"
Set-ScheduledTask -InputObject $task