Weekend Scripter: Use PowerShell to Document Scheduled Tasks


Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to document scheduled tasks.

Microsoft Scripting Guy, Ed Wilson, is here. One of the really cool things about Windows PowerShell is the way that it builds on itself. When I learn a little bit about Windows PowerShell, I can apply those principles to accomplish other things. It does not matter what I am working with, Windows PowerShell works the same. Today, I have a great example.

I have seen several comments, and even received a few emails to scripter@microsoft.com asking about documenting scheduled tasks. People generally want to know the action that a task is supposed to do, and what the last results of that task were. If they can get the output in a CSV file so they can open it in Microsoft Excel, so much the better.

I thought this would be a cool way to end Scheduled Tasks Week. So here is a script—not too complicated—that does the following:

  1. Obtains a list of all scheduled tasks, beginning with a specific folder, and performs a recursive lookup for scheduled tasks in that folder and all subfolders.
  2. Creates a custom Windows PowerShell object that contains the name, status, results, next run time, execution command, and arguments for that command.
  3. Exports the custom object to a CSV file for further analysis.

To accomplish these objectives, I'll use the following Windows PowerShell cmdlets and functions:

  • Get-ScheduledTask
  • Foreach-Object
  • Get-ScheduledTaskInfo
  • Export-CSV

In addition to these functions and cmdlets, I'll use a hash table to create a custom Windows PowerShell object by using the [PSCustomObject] type accelerator. I also use a subexpression to obtain the last run value and the next run value from embedded objects.

The first thing I do is create two variables and assign string values to them. The $taskPath variable holds the path to scheduled tasks folders. $taskPath notation requires a backslash ( \ ) at the beginning and end of the string. I use an asterisk ( * ) as a wildcard character to search through all of the folders. Here is the command:

$taskPath = "\microsoft\*\"

$outcsv = "c:\fso\taskdef.csv"

The scheduled task folder structure is shown here:

Image of menu

Now I use the Get-ScheduledTask function to retrieve all of the scheduled task objects from the folders. I pipe the scheduled task objects to the Foreach-Object cmdlet so that I can create a custom object from each task as it comes across the pipeline. Here is that section of the script:

Get-ScheduledTask -TaskPath $taskPath |

    ForEach-Object { [pscustomobject]@{

The [pscustomobject] type accelerator accepts a hash table. Therefore, I begin and close the hash table as shown here:

@{}

In between the braces, I use a value for my property name, and I set it equal to an expression on the other side. The first one is easy—I get the task name and path:

Name = $_.TaskName

Path = $_.TaskPath

The next two things I want are the last result and the next time it will run. These come from the results of the Get-ScheduledTaskInfo function. I use a subexpression to cause the code to execute, and to bring back the results so I can assign it to my property values. Here is that code:

LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)

NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)

As shown here, I pick up the state of the scheduled task. Is it ready to run, running, disabled, or “what have ya”?:

Status = $_.State

The command that will execute and arguments to that command are from objects embedded in the Actions property of my scheduled task object. I can use dotted notation to retrieve those values:

Command = $_.Actions.execute

Arguments = $_.Actions.Arguments

I pipe the output to the Export-CSV cmdlet and create the CSV file. I use the –NoTypeInformation parameter to prevent the creation of a type header in the CSV file. Here is that command:

Export-Csv -Path $outcsv -NoTypeInformation

The complete script is shown here:

$taskPath = "\microsoft\*\"

$outcsv = "c:\fso\taskdef.csv"

Get-ScheduledTask -TaskPath $taskPath |

    ForEach-Object { [pscustomobject]@{

     Name = $_.TaskName

     Path = $_.TaskPath

     LastResult = $(($_ | Get-ScheduledTaskInfo).LastTaskResult)

     NextRun = $(($_ | Get-ScheduledTaskInfo).NextRunTime)

     Status = $_.State

     Command = $_.Actions.execute

     Arguments = $_.Actions.Arguments }} |

        Export-Csv -Path $outcsv -NoTypeInformation

Here is the CSV file when I open it in Microsoft Excel:

Image of spreadsheet

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Comments (1)

  1. Tyger says:

    How would this be used to document scheduled tasks at the server level

Skip to main content