Manage Scheduled Tasks in Windows 8 and Windows Server 2012 with PowerShell : Part 1

One of the most useful features in Windows 8 and Windows Server 2012 is the ability to manage scheduled tasks from PowerShell. No more relying on the legacy workhorse schtasks.exe or trying to wrap it up in fancy PowerShell commands — now we have true cmdlets. In the next few articles, we’ll explore how to take advantage of this feature.
In this first article I’ll teach you how to use the ScheduledTasks module to retrieve information about scheduled tasks. In part two, I’ll walk through creating a new scheduled task using PowerShell.

Requirements for Scheduled Tasks

First things first. Managing scheduled tasks comes to us courtesy of the ScheduledTasks module. While this also requires PowerShell v3, the module can only be found on Windows 8 and Windows Server 2012 platforms. That means that even if you have PowerShell v3 running on Windows 7 or Windows Server 2008 R2, you don’t get this feature. In those situations, you’ll have to continue managing scheduled tasks as you are now. Note: Don’t confuse this with scheduled jobs – that is a feature of PowerShell v3, which means you have it anywhere v3 is installed.

How to Get a List of Scheduled Tasks

To get a list of all scheduled tasks, all you need to do is ask.

​PS C:\> Get-ScheduledTask

Below, Figure 1 depicts what you can expect on a Windows 8 system.
 
Get Scheduled Tasks
Because PowerShell autoloads modules, you don’t even have to import the ScheduledTasks module. The default behavior is to get all tasks. But you can limit your search by a task name.

​PS C:\> Get-ScheduledTask -TaskName ScheduledDefrag
TaskPath                                   TaskName                 State
--------                                   --------                 -----
\Microsoft\Windows\Defrag\                 ScheduledDefrag          Ready

Or you can retrieve tasks based on the “folder” or path.

PS C:\> Get-ScheduledTask -TaskPath “*defender\”   TaskPath                                TaskName                    State ——–                                ——–                    —– \Microsoft\Windows\Windows Defender\    Windows Defender Cache Ma… Ready \Microsoft\Windows\Windows Defender\    Windows Defender Cleanup     Ready \Microsoft\Windows\Windows Defender\    Windows Defender Schedule… Ready \Microsoft\Windows\Windows Defender\    Windows Defender Verifica… Ready

In either situation you can use wildcards which makes it pretty easy. The –Taskname parameter is positional so you can run commands like this:

PS C:\> get-scheduledtask synchronizetime

Getting Remote Tasks

You can easily connect to one or more remote Windows 8 or Windows Server 2012 systems using the CIMSession parameter. You can pass a computer name and PowerShell will automatically create a CIM session to the remote computer. PowerShell remoting must be enabled and properly configured for this to work.

PS C:\> get-scheduledtask synchronizetime -CimSession chi-win8-01,chi-dc03   TaskPath                                 TaskName        State PSComputerName ——–                                 ——–        —– ————– \Microsoft\Windows\Time Synchronization\ SynchronizeTime Ready chi-dc03 \Microsoft\Windows\Time Synchronization\ SynchronizeTime Ready chi-win8-01

These CIM sessions are only temporary for this command. But if you have open CIM Sessions for other purposes, you can use them here.

PS C:\> $cims = New-CimSession -ComputerName chi-dc03,chi-win8-01

This creates CIM sessions to the specified computers. Now I can get-scheduled tasks from them.

PS C:\> get-scheduledtask *defrag -cim $cims   TaskPath                   TaskName        State PSComputerName ——–                   ——–        —– ————– \Microsoft\Windows\Defrag\ ScheduledDefrag Ready chi-dc03 \Microsoft\Windows\Defrag\ ScheduledDefrag Ready chi-win8-01

The Task Object

The scheduled task object is quite rich.

PS C:\> get-scheduledtask synchronizetime | select *

The results are shown in below Figure 2.
 
Scheduled Task Object
For example, you may want to learn more about the disabled tasks on your computer.

PS C:\> get-scheduledtask |  where {$_.state -eq “disabled”} | format-table TaskName,Description –wrap

My results are in Figure 3.
Scheduled Task Report
 

The Get-ScheduledTaskInfo Cmdlet

The last reporting feature I want to cover is the Get-ScheduledTaskInfo cmdlet. This cmdlet returns information about the task result. The easiest way to use this cmdlet is to pipe a task object to it.

PS C:\> get-scheduledtask synchronizetime | get-scheduledtaskinfo     LastRunTime        : 9/27/2012 2:58:58 PM LastTaskResult     : 0 NextRunTime        : NumberOfMissedRuns : 0 TaskName           : SynchronizeTime TaskPath           : \Microsoft\Windows\Time Synchronization\ PSComputerName     :

As you can see, the critical properties are when the task ran and its result. Like most things in Windows, a value of 0 indicates success. You can use this information in a reporting command like this:
 

PS C:\> get-scheduledtask -cimsession chi-dc03 | where {$_.state -notmatch “disabled|Running”} | get-scheduledtaskinfo | Select PSComputername,TaskName,LastRunTime,LastTaskResult

This expression is getting all tasks from CHI-DC03 that are not disabled or running. These tasks are passed to Get-ScheduledTaskInfo, which in turn is piped to Select-Object to return a few key properties as you can see in Figure 4.
Getting Scheduled Task Last Run Data
 
As you can see, some tasks have never run. It wouldn’t take that much more work to report only tasks that failed.

PS C:\> get-scheduledtask -cimsession chi-dc03 | where {$_.state -notmatch “disabled|Running”} | get-scheduledtaskinfo | Where { $_.LastTaskResult -ne 0} | Select PSComputername,TaskName,LastRunTime,LastTaskResult

 
Managing scheduled tasks from Windows 8 is not difficult once you understand how cmdlet fundamentals. Yes, it does require Windows 8 or Windows Server 2012, but hopefully those will eventually make their way into most enterprises. In the next article, we’ll begin looking at creating scheduled tasks.