Powershell Scheduled Task At Startup Repeating - powershell

I'm trying to create a Scheduled Task with the following Trigger:
- Startup
- Run every 5 minutes
- Run indefinitely
In the GUI I can do this easily by selecting:
- Begin the task: at startup
And in the Advanced tab:
- Repeat task every: 5 minutes
- For a duration of: indefinitely
But I'm having trouble doing it with Powershell.
My troubled code:
$repeat = (New-TimeSpan -Minutes 5)
$duration = ([timeSpan]::maxvalue)
$trigger = New-ScheduledTaskTrigger -AtStartup -RepetitionInterval $repeat -RepetitionDuration $duration
It won't take the RepetitionInterval and RepetitionDuration parameters. But I need that functionality.
How could I accomplish my goal?

To set the task literally with a "Startup" trigger and a repetition, it seems you have to reach in to COM (or use the TaskScheduler UI, obviously..).
# Create the task as normal
$action = New-ScheduledTaskAction -Execute "myApp.exe"
Register-ScheduledTask -Action $action -TaskName "My Task" -Description "Data import Task" -User $username -Password $password
# Now add a special trigger to it with COM API.
# Get the service and task
$ts = New-Object -ComObject Schedule.Service
$ts.Connect()
$task = $ts.GetFolder("\").GetTask("My Task").Definition
# Create the trigger
$TRIGGER_TYPE_STARTUP=8
$startTrigger=$task.Triggers.Create($TRIGGER_TYPE_STARTUP)
$startTrigger.Enabled=$true
$startTrigger.Repetition.Interval="PT10M" # ten minutes
$startTrigger.Repetition.StopAtDurationEnd=$false # on to infinity
$startTrigger.Id="StartupTrigger"
# Re-save the task in place.
$TASK_CREATE_OR_UPDATE=6
$TASK_LOGIN_PASSWORD=1
$ts.GetFolder("\").RegisterTaskDefinition("My Task", $task, $TASK_CREATE_OR_UPDATE, $username, $password, $TASK_LOGIN_PASSWORD)

New-ScheduledTaskTrigger uses parameter sets. When you specify that you want the scheduled task to start up "at logon" you are restricting yourself to the following parameter set:
Parameter Set: AtStartup
New-ScheduledTaskTrigger [-AtStartup] [-RandomDelay <TimeSpan> ] [ <CommonParameters>]
What may be more beneficial is if you use your "at startup" scheduled task to register a new scheduled task to run every five minutes using the "once" parameter set:
Parameter Set: Once
New-ScheduledTaskTrigger [-Once] -At <DateTime> [-RandomDelay <TimeSpan> ] [-RepetitionDuration <TimeSpan> ] [-RepetitionInterval <TimeSpan> ] [ <CommonParameters>]
Your Scheduled Task Trigger should successfully be assigned once you are using the correct parameter set.

See my answer here: https://stackoverflow.com/a/61646465/2943191
It is actually relatively simple, once a working example is written, of course.
Instead of -AtLogOn use -AtStartup.

For what it’s worth, I too ran into this issue as I was particularly perturbed that this functionality was pulled from PowerShell for -AtStartup. However, upon further review, the same functionality can be performed by just be using -Once and configuring it to repeat. In the OP’s case of having this run every five minutes, it probably won’t make a difference if this is run at startup or five minutes thereafter.
I have confirmed this with -Once and then configuring it to repeat. It will also perform the repeats when the system is restarted. This is somewhat different from #BryceMcDonald’s answer in that you don’t need to create two triggers—just create the -Once one and you’ll be good to go.

Related

Specify location with Task Scheduler script

I'm trying to write a PowerShell script that will activate another script on a daily basis. What I have is:
$Sta = New-ScheduledTaskAction -Execute "powershell.exe" -argument "C:\Users\UserName\Desktop\Script.ps1"
$Stt = New-ScheduledTaskTrigger -Daily -At 3am
Register-ScheduledTask Task1 -Action $Sta -Trigger $Stt
It's not working because it can't find the file. PowerShell's default directory is the user's root directory, so I don't know if that's it, even though I've tried using the full path to the file? Or is it due to where the scheduled task is running from? Location says \ and I cannot seem to change that, even in the task scheduler app. I've been Googling for days and I can't figure it out. Anyone have any idea? I'm working on Windows 10 Pro.
Soufflegirl13,
Updated & Tested:
$TaskSet = New-ScheduledTaskSettingsSet -Compatibility Win8
$TaskSet.DisallowStartIfOnBatteries = $True
$TaskSet.StopIfGoingOnBatteries = $True
$TaskSet.IdleSettings.StopOnIdleEnd = $false
#Adjust the following two lines to meet your requirements
$TaskDesc = "Retrieve the status of HyperV"
$TaskName = "Task1 - or whatever you want here"
$Stt = New-ScheduledTaskTrigger -Daily -At 3am
#Adjust the -file parameter to point to your script
$TAArgs = #{Execute = '"' + "c:\windows\system32\windowspowershell" +
"\v1.0\powershell.exe" + '"' ;
Argument = "-file `"G:\BEKDocs\Scripts\Misc\Get-HyperVStatus-V-3.ps1`"" }
$TaskAction = New-ScheduledTaskAction #TAArgs
$RSTArgs = #{Action = $TaskAction
TaskName = "$TaskName"
Trigger = $Stt
User = "$env:USERDOMAIN\$env:username"
RunLevel = "Highest"
Description = "$TaskDesc"
Settings = $TaskSet}
Register-ScheduledTask #RSTargs
I've found that forcing the quote marks around the powershell filespec solved some problems. You might want to try it around the script name if the previous doesn't work.
Of course adjust any settings as you see fit to meet your requirements. Also I've not used this basic code to set a trigger before but I adjusted it to do so according to the documentation for Register-ScheduledTask so it should work.
Update Notes:
I checked the documentation for the New-ScheduledTaskSettingsSet cmdlet and it doesn't include Win10 as a valid value for Compatibility, go figure, so I backed it off to Win8. You can also just not use the Compatibility argument and accept whatever it defaults to.
The code is now fully tested, sorry I forgot to tell you to replace the $TaskName variable with a value or to add the variable, as is now shown in the adjusted code.
HTH

Setting Multiple-Day notification with Powershell3

Set-CalenderNotification provides a one time notification functionality with emails , but the notification is only restricted to one .
If one wants to set up a Multiple-Day notification (similar to Task Scheduler which outputs a GUI message prompt on these days) ,is there any command available in Powershell( other than settings it up entirely by polling the dates using the Get-Date cmdlet)?
Also,is there any way to access TaskScheduler as an Object with Powershell (inorder to use the Multiple-Day notification feature ) ?
New-ScheduledTaskTrigger creates a scheduled task trigger object,which provides the options to provide multiple day notification.
Syntax
New-ScheduledTaskTrigger
[-RandomDelay <TimeSpan>]
-At <DateTime>
[-DaysOfWeek <DayOfWeek[]>]
[-Weekly]
[-WeeksInterval <UInt32>]
Example
New-ScheduledTaskTrigger -Weekly -WeeksInterval 2 -DaysOfWeek Sunday -At 3am

How to configure "If the task is already running, then the following rule applies" in Windows Task Scheduler using PowerShell script?

I am trying to achieve the following settings (select "If the task is already running, then the following rule applies") through PowerShell script but unable to get appropriate settings to configure that.
I am using the following code to configure that
$Trigger = New-ScheduledTaskTrigger -At 07:00am -Daily
$Settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Hour 1) -Compatibility Win7 -StartWhenAvailable -Priority 7
$User = "SYSTEM"
$Action = New-ScheduledTaskAction -Execute "some script" -Argument "some argument" -WorkingDirectory "working dir"
Register-ScheduledTask -TaskName "Test Task" -Trigger $Trigger -User $User -Action $Action -Settings $Settings -RunLevel Highest –Force
To do the advanced configuration for the triggers
$Task = Get-ScheduledTask -TaskName "Example Task"
$Task.Triggers[0].ExecutionTimeLimit = "PT10M"
$Task | Set-ScheduledTask -User $User
The setting is configured via New-ScheduledTaskSettingsSet and the parameter you're looking for is -MultipleInstances:
-MultipleInstances
Specifies the policy that defines how Task Scheduler handles multiple instances of the task. The acceptable values for this parameter are:
IgnoreNew. The new task instance is ignored. Parallel. The new task instance starts immediately. Queue. The new task instance starts as soon as the current instance completes.
Type: MultipleInstancesEnum
Accepted values: Parallel, Queue, IgnoreNew
Position: Named
Default value: None
However, the documentation lists only 3 values, and the respective enum (at least at the time of this writing also only has the listed 3 values:
Parallel → Run a new instance in parallel
Queue → Queue a new instance
IgnoreNew → Do not start a new instance
If you create a task manually via the GUI and select the setting "Stop the existing instance" the value .Settings.MultipleInstances is empty, but if you create a Settings object via New-ScheduledTaskSettingsSet omitting the parameter -MultipleInstances it defaults to IgnoreNew. Attempts to change that to an empty value result in validation errors.
This is obviously a bug (missing value in the referenced enum).
The enum now contains 'StopExisting'.
This is my solution in C#.
static void RegisterMyTask(string taskPath, string remoteServer)
{
try
{
using TaskService ts = new(remoteServer);
TaskDefinition taskDef = ts.NewTask();
taskDef.Settings.MultipleInstances = TaskInstancesPolicy.StopExisting;
...
However PowerShell probably has the new enum as well. As I would guess:
-MultipleInstances StopExisting
I had a task scheduled on multiple remote servers.
On day 1 it started running.
Day 2 it failed to start a new instance, but didn't kill the existing instance
Day 3 it failed to start a new instance, but didn't kill the existing instance. Then 30 seconds later, the existing instance was killed by the day 1 timeout setting, but the new instance had already failed for the day.
This fixed my problem.

Enable task to be deleted after X time

How can I enable a task created using PowerShell's Register-ScheduledTask to be deleted If the task is not scheduled to run again? As in New-JobTrigger -Once -At $ScheduledTime
The option is seen in the Task Scheduler GUI > Task Properties > Settings tab > The last checkbox option reads:
If the task is not scheduled to run again, delete it after: <time period>
MS TechNet article Searching for enabling this option using PowerShell does not turn up any relevant results, mostly how to enable tasks and so on.
You should use a New-ScheduledTaskSettingsSet like
New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter <TimeSpan>
$STSet = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter <TimeSpan>
Register-ScheduledTask mytask -Action <actionobject> -Settings $STSet

Powershell - Monthly Scheduled Task Trigger

I'm currently automating the creation of scheduled tasks via Powershell, and I'm using the New-ScheduledTaskAction, New-ScheduledTaskTrigger, and Register-ScheduledTask commands. Now, I have a few jobs that need to run under the following conditions :
Run once every Friday
Run once on the 1st of every month
Run once on the 10th day of every month
While the technet documentation for the New-ScheduledTaskTrigger command specifies a Daily and Weekly time span parameter, I do not see one for Monthly, which is critical for defining the run times above.
In the few years I've been using Powershell, I can't think of an instance where I could do something via the standard UI interface, that I couldn't accomplish using one of the available commands.
Is this just flat out not available here, or am I missing something?
UPDATE #1
I just stumbled upon this SuperUser question, which does look promising, but references PSV3 instead of PSV4 - going to give it a shot and report back.
As I said in the original post, the SuperUser question above looked promising, but ultimately did not work with PSV4, and the example given in the post was basically a copy\paste job with almost no context.
I realized I could leverage Schtasks.exe from my Powershell script to handle the monthly aggregations, and it's fairly easy to set up, albeit somewhat tedious :
# set the trigger depending on time, span, and day
$runSpan = $task.SpanToRun;
if ($runSpan.Equals("Daily"))
{
$trigger = New-ScheduledTaskTrigger -Daily -At $task.TimeToRun
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $task.TaskName -User $Username -Password $Password -Description $task.Description
}
if ($runSpan.Equals("Weekly"))
{
$trigger = New-ScheduledTaskTrigger -Weekly -At $task.TimeToRun -DaysOfWeek $task.DayToRun
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $task.TaskName -User $Username -Password $Password -Description $task.Description
}
# script out SchTasks magic to create the monthly tasks
if ($runSpan.Equals("Monthly"))
{
$taskParams = #("/Create",
"/TN", $task.TaskName,
"/SC", "monthly",
"/D", $task.DayToRun,
"/ST", $task.TimeToRun,
"/TR", $filePath,
"/F", #force
"/RU", $Username,
"/RP", $Password);
# supply the command arguments and execute
#schtasks.exe $taskParams
schtasks.exe #taskParams
}
I'm using an in-script class to keep track of all the task properties ($task.TimeToRun, $task.DayToRun, etc.), iterating over a list of those, applying the Powershell implementation for daily and weekly tasks, then switching to SchTasks.exe for the monthly spans.
One thing I want to note, is that at first glance, I thought setting the user context under which the task runs could be achieved with the U and P arguments, but that is not the case. That specifies the creds that Schtasks.exe runs under - in order to set the user context for the task, you must use RU and RP.
In addition to the link above, these two were also very helpful :
http://coding.pstodulka.com/2015/08/02/programmatically-scheduling-powershell-scripts-in-task-scheduler/
https://msdn.microsoft.com/en-us/library/windows/desktop/bb736357(v=vs.85).aspx