Prof. Powershell

I'll Get to It Later: Managing Scheduled Tasks with PowerShell in Windows 8

Part 1 on managing scheduled tasks with the ScheduledTasks module in the upcoming PowerShell 3.

PowerShell 3.0 will have a dramatic impact on how IT pros manage their Windows environments, especially as they move to Windows 8 and Windows Server 2012. One big change is the ability to natively manage scheduled tasks from PowerShell. This means that if you can manage a scheduled task on one machine, from setting it up to disabling it to auditing what tasks are currently deployed, you can do it on 10 or 1,000 systems.

And none of this will require any scripting.

To manage scheduled tasks from PowerShell you need to use the ScheduledTasks module. As of now, this module is only available on Windows 8 and Windows Server 2012. In PowerShell 3.0, you don't have to import a module before you use any commands. If you know the cmdlet name, you can simply run it. But let's import the module anyway so we can see what we have to work with. By the way, all of tasks we will want to run must be run from an elevated session:

PS C:\> Import-Module ScheduledTasks
PS C:\> Get-Command -Module ScheduledTasks

Figure 1 shows the output.

ScheduledTasks commands

Figure 1. ScheduledTasks commands. (Click image to view larger version.)

Because I don't have a cluster, I'll skip the Clustered versions but they should work much like everything else I'm going to cover here.

First, let's see about finding what is currently scheduled using Get-ScheduledTask.

PS C:\> $tasks=Get-ScheduledTask
PS C:\> $tasks.count

On my Windows 8 system I have 116 scheduled tasks. To query a remote computer, the cmdlet uses the new CIM cmdlets, which I'll cover in another lesson. For now, know that the remote computer must be running PowerShell 3.0 but it doesn't have to be Windows 8 or Server 2012 because it is querying WMI via a CIM session (see Fig. 2):

PS C:\> get-scheduledtask -CimSession quark

Remote Scheduled Tasks via a CIM Session.

Figure 2. Remote Scheduled Tasks via a CIM Session. (Click image to view larger version.)

You can also get a task by its name, wildcards are permitted:

PS C:\> get-scheduledtask *defender*

Or by its path:

PS C:\> get-scheduledtask -taskpath *update*

My results are in Fig. 3.

Getting Scheduled Tasks by Name and Path

Figure 3. Getting Scheduled Tasks by Name and Path. (Click image to view larger version.)

But let's return and work locally, checking out one of these tasks:

PS C:\> $task=Get-scheduledtask "Windows Defender Scheduled Scan"
PS C:\> $task | Select *

State                 : Ready
Actions               : {MSFT_TaskExecAction}
Author                :
Date                  :
Description           : Periodic scan task.
Documentation         :
Principal             : MSFT_TaskPrincipal2
SecurityDescriptor    :
Settings              : MSFT_TaskSettings3
Source                :
TaskName              : Windows Defender Scheduled Scan
TaskPath              : \Microsoft\Windows\Windows Defender...
Triggers              :
URI                   : \Microsoft\Windows\Windows Defender...
Version               :
PSComputerName        :
ComputerName          : WIN8CP
ClassName             : MSFT_ScheduledTask
Class                 : Root/Microsoft/Windows/TaskSchedule...
CimClass              : Root/Microsoft/Windows/TaskSchedule...
Namespace             : Root/Microsoft/Windows/TaskScheduler
Properties            : {Actions, Author, Date, Description...}
CimInstanceProperties : {Actions, Author, Date, Description...}
CimSystemProperties   : Microsoft.Management.Infrastructure...

This is a pretty rich object which makes for some excellent reporting. The properties of interest here are Actions, Principal, and Triggers.

Actions indicates what the scheduled task is going to do:

PS C:\> $task.actions

Id               :
Arguments        : Scan -ScheduleJob
Execute          : %ProgramFiles%\Windows Defender\MpCmdRun.exe
WorkingDirectory :
PSComputerName   :

Principal tells you what account the task is running under:

PS C:\> $task.Principal

DisplayName         :
GroupId             :
Id                  : LocalSystem
LogonType           : ServiceAccount
RunLevel            : Highest
UserId              : SYSTEM
ProcessTokenSidType : Default
RequiredPrivilege   :
PSComputerName      :

Triggers shows when the task will run. This task doesn't have a defined trigger so let me grab a task that does:

PS C:\> get-scheduledtask ProcessMemoryDiagnosticEvents | select -ExpandProperty Triggers| Select -first 1

Enabled            : True
EndBoundary        :
ExecutionTimeLimit :
Id                 :
Repetition         : MSFT_TaskRepetitionPattern
StartBoundary      :
Delay              :
Subscription       : <QueryList><Query Id="0" Path="System">
                     SystemErrorReporting'] and (EventID=1000
                     or EventID=1001 or EventID=1006)]]
ValueQueries       :
PSComputerName     :

This particular task has multiple triggers so I'm just grabbing one. This particular trigger is based on an event subscription.

That's a quick look at the basics and what we have to work with. Next time we'll look at creating our own scheduled tasks.

Note: This article is based on a pre-release version of PowerShell 3.0 and Windows 8.

About the Author

Jeffery Hicks is an IT veteran with over 25 years of experience, much of it spent as an IT infrastructure consultant specializing in Microsoft server technologies with an emphasis in automation and efficiency. He is a multi-year recipient of the Microsoft MVP Award in Windows PowerShell. He works today as an independent author, trainer and consultant. Jeff has written for numerous online sites and print publications, is a contributing editor at, and a frequent speaker at technology conferences and user groups.

comments powered by Disqus
Most   Popular