Creation of a Scheduled task in PowerShell 3.0

Microsoft introduced the new cmdlets for scheduled tasks with PowerShell 3.0 in Windows 8 and Windows Server 2012. It’s now easier to script those scheduled tasks and a lot of possibilities are now open to us. Unfortunately, as we will see, there are still some limitations in the given new cmdlets. However, there is a workaround for that which is really helpful and maybe easier to put in place than scripting everything.

Method 1: Scripting a scheduled task

Bit by bit

For our first way of scripting a scheduled task with PowerShell, we will have to define at minimum some variables with metadata, an action, a trigger, some settings and then, we will be able to register this task to the Task Scheduler.

Metadata

First, you will have to name and optionally describe your task. We will use variables for that matter.

$taskname = "Restart My Service 1"
$taskdescription = "Restart My Service 1 every day at 9am"

 

Action

Once it is done, you need to specify your action (what the task will do when it’s triggered).Here, the action is to launch an instance of PowerShell and restart a service “My Service 1” via a cmdlet.

Here, the action is to launch an instance of PowerShell and restart a service “My Service 1” via a cmdlet.

$action = New-ScheduledTaskAction -Execute 'PowerShell.exe' `
  -Argument '-NoProfile -WindowStyle Hidden -command "& Restart-Service -displayname \"My Service 1\""'

NB: You will have to respect the spaces and the break line of that code.

Options for New-ScheduledTaskAction : https://technet.microsoft.com/en-us/library/jj649817.aspx

 

Trigger

It’s now time to add a trigger to your task. It will define when or why your task will be launched.

You can trigger your action to be launched at a specific time with -Once, or make it recursive with -Daily or -Weekly. It’s also possible to make it run only -AtLogon or -AtStartup.

Examples of different triggers:

$trigger = New-ScheduledTaskTrigger -Daily -At 9am

It will run every day at 9 am.

$trigger = New-ScheduledTaskTrigger -AtStartup -RandomDelay (New-TimeSpan -minutes 3)

It will run 3 minutes after your computer has started.
This cmdlet is still a bit restrictive as the number of options doesn’t reflect what you can do with the GUI. For example, with the GUI you can run your task after a specific event has happened or use a custom filter. That can be useful if you want to run your task after another one has been completed for example.

Options for New-ScheduledTaskTrigger : https://technet.microsoft.com/en-us/library/jj649821.aspx

 

Settings

With the cmdlet New-ScheduledTaskSettingsSet, you can specify how the task will behave given specific parameters like:
– is the computer is on battery?
– is that network is available?
– is the task has failed?

Example:

$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -RunOnlyIfNetworkAvailable -NetworkName "Network 2"

-ExecutionTimeLimit (New-TimeSpan -Minutes 2): If the task is not finished after 2 minutes, it is considered as failed
-RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1): If the task fails, it will be restarted after 1 minute. That behaviour will be repeated 3 times before being abandoned.
-RunOnlyIfNetworkAvailable -NetworkName “Network 2”: the task will run only if a specific network named Network 2 is available

Options for New-ScheduledTaskSettingsSet : https://technet.microsoft.com/en-us/library/jj649824.aspx

 

Registering a task

Finally, we are there, we can register the task we created bit by bit. We will use each variable previously set and we will add some specific arguments in order to define the user who will be used to run the task.

Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskname -Description $taskdescription -Settings $settings -User "System" -RunLevel Highest

 

Some options:

-User “System”: run as the built-in SYSTEM account
-User “$env:USERDOMAIN\$env:USERNAME”: run as a user of a domain
-Password ‘jn84xf-donmb’: if you need a password for the specified account, you can add it there
-RunLevel Highest: run as the highest privilege

 

Full script

# Purpose
# Create a scheduled task which will restart My Service 1 each day at 9am
$taskname = "Restart My Service 1"
$taskdescription = "Restart My Service 1 every day at 9am"
$action = New-ScheduledTaskAction -Execute 'PowerShell.exe' `
-Argument '-NoProfile -WindowStyle Hidden -command "& Restart-Service -displayname \"My Service 1\""'
$trigger = New-ScheduledTaskTrigger -Daily -At 9am
$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 2) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1) -RunOnlyIfNetworkAvailable -NetworkName "Network 2"
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName $taskname -Description $taskdescription -Settings $settings -User "System" -RunLevel Highest

 

Method 2: Importing an XML scheduled task with PowerShell

As there are some limitations in the cmdlet New-ScheduledTaskTrigger, it can be necessary to import an XML to register a more customized task with PowerShell.

You can produce an XML either by hand or by exporting a current task from the Task Scheduler (which will be easier).

After you produce your XML file, you just have to register your task and name it (when you export a scheduled task, the name is ripped off of the XML file):

Register-ScheduledTask -Xml (Get-Content 'C:\temp\scheduledTaskRestartMyService1.xml' | out-string) -TaskName "Restart My Service 1"

 

Example of a scheduled task in XML with a custom event filter

This task has been exported without modification from the Task scheduler.
When enabled, this task is executed 30 seconds after the task “The Alpha Service” is completed and the network “Network 2” is available.
Furthermore, if the tasks fails, it will be relaunched 3 times.

<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.3" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
 <RegistrationInfo>
 <Date>2016-02-12T11:35:03.7591309</Date>
 <Author>COMPUTER01\TempEC2User</Author>
 <Description>Restart My Service 1 when The Alpha Service task is completed successfully.</Description>
 </RegistrationInfo>
 <Triggers>
 <EventTrigger>
 <Enabled>true</Enabled>
 <Subscription>&lt;QueryList&gt;&lt;Query Id="0" Path="Microsoft-Windows-TaskScheduler/Operational"&gt;&lt;Select Path="Microsoft-Windows-TaskScheduler/Operational"&gt;*[EventData
[@Name='TaskSuccessEvent'][Data[@Name='TaskName']='\The Alpha Service']]&lt;/Select&gt;&lt;/Query&gt;&lt;/QueryList&gt;</Subscription>
 <Delay>PT30S</Delay>
 </EventTrigger>
 </Triggers>
 <Principals>
 <Principal id="Author">
 <UserId>S-1-5-18</UserId>
 <RunLevel>LeastPrivilege</RunLevel>
 </Principal>
 </Principals>
 <Settings>
 <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
 <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
 <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
 <AllowHardTerminate>true</AllowHardTerminate>
 <StartWhenAvailable>false</StartWhenAvailable>
 <RunOnlyIfNetworkAvailable>true</RunOnlyIfNetworkAvailable>
 <NetworkSettings>
 <Name>Network 2</Name>
 <Id>{5F8E4AA3-8D6F-895C-A746-4F1DE4B95213}</Id>
 </NetworkSettings>
 <IdleSettings>
 <StopOnIdleEnd>true</StopOnIdleEnd>
 <RestartOnIdle>false</RestartOnIdle>
 </IdleSettings>
 <AllowStartOnDemand>true</AllowStartOnDemand>
 <Enabled>true</Enabled>
 <Hidden>false</Hidden>
 <RunOnlyIfIdle>false</RunOnlyIfIdle>
 <DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
 <UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
 <WakeToRun>false</WakeToRun>
 <ExecutionTimeLimit>PT2M</ExecutionTimeLimit>
 <Priority>7</Priority>
 <RestartOnFailure>
 <Interval>PT1M</Interval>
 <Count>3</Count>
 </RestartOnFailure>
 </Settings>
 <Actions Context="Author">
 <Exec>
 <Command>Powershell.exe</Command>
 <Arguments>-NoProfile -WindowStyle Hidden -command "&amp; Restart-Service -displayname \"My Service 1\""</Arguments>
 </Exec>
 </Actions>
</Task>

 

Resources

Documentation at Microsoft on Scheduled Task Cmdlets in Windows PowerShell: https://technet.microsoft.com/en-us/library/jj649816.aspx

 

Credits

Thanks to those articles:
http://blogs.msdn.com/b/davethompson/archive/2011/10/25/running-a-scheduled-task-after-another.aspx
https://blogs.technet.microsoft.com/heyscriptingguy/2015/01/13/use-PowerShell-to-create-scheduled-tasks/
https://www.petri.com/import-scheduled-tasks-PowerShell

Leave a Reply

Your email address will not be published. Required fields are marked *