Powershell v4. Create remote task scheduler task set to expire and delete

爱⌒轻易说出口 提交于 2019-12-29 09:17:10

问题


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.

$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

回答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:

$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.

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.




回答2:


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

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

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).

Other Prerequisites

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

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

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

$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)



回答3:


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.

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.

$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


来源:https://stackoverflow.com/questions/29337135/powershell-v4-create-remote-task-scheduler-task-set-to-expire-and-delete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!