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

2

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
powershell
scheduled-tasks
asked on Stack Overflow Mar 30, 2015 by Doms • edited Mar 30, 2015 by AstroCB

4 Answers

4

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.

answered on Stack Overflow Mar 3, 2016 by Satori-Stan
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

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)
answered on Stack Overflow Mar 30, 2015 by Jan Chrbolka • edited Mar 31, 2015 by Jan Chrbolka
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.

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
answered on Stack Overflow May 30, 2017 by Aaron
0
$Action = New-ScheduledTaskAction -Execute powershell.exe -Argument "-WindowStyle Hidden -Command Get-Date"
$Trigger = New-ScheduledTaskTrigger -AtLogon
$Settings = New-ScheduledTaskSettingsSet -Compatibility Win8
$Principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest
$Parameters = @{
    "TaskName"    = "test"
    "Principal"   = $Principal
    "Action"      = $Action
    "Settings"    = $Settings
    "Trigger"     = $Trigger
}
Register-ScheduledTask @Parameters -Force

# In order to use DeleteExpiredTaskAfter, you need to set an StartBoundary & EndBoundary date/time to the trigger
$TargetTask = Get-ScheduledTask -TaskName "test"
$TargetTask.Triggers[0].StartBoundary = [DateTime]::Now.ToString("yyyy-MM-dd'T'HH:mm:ss")
$TargetTask.Triggers[0].EndBoundary = [DateTime]::Now.AddDays(1).ToString("yyyy-MM-dd'T'HH:mm:ss")
# If the task is not scheduled to run again, delete it after: immediately
$TargetTask.Settings.DeleteExpiredTaskAfter = "PT0S"
$TargetTask | Set-ScheduledTask
answered on Stack Overflow Mar 26, 2021 by farag

User contributions licensed under CC BY-SA 3.0