Running a scheduled PowerShell script on a pre-Vista OS

It's been fun to see the reception that PowerShell has gotten. People are using it for tons of different stuff and the ingenuity in some of the scenarios is quite impressive. There is one thing, however, that you should be aware of. PowerShell is not an ideal candidate for execution through the Task Scheduler.

Problem

A long-running PowerShell script is being executed using the Task Scheduler. At apparently random intervals the script will fail with a System.Management.Automation.PipelineStoppedException.

Cause

Looking up the exception on MSDN might not shed any light on the situation unless you know what is happening.

The exception thrown when a cmdlet or a Windows PowerShell provider attempts to write to the pipeline or perform a number of other Windows PowerShell operations after the pipeline has been terminated. The pipeline could have been terminated before the call was made or during the call.

When the Task Scheduler executes a PowerShell script it needs to use the .NET Framework. When running the .NET Framework it uses the console session (Session 0). This problem occurs when someone is logged on to the root console (either physically or using Terminal Services) and logs off while the script is executing.

Repro

You can easily reproduce this by creating a small script that sleeps for a while. Schedule the script to run immediately and then log off. To illustrate I've used the following script:

function Main()
{
     Start-Transcript "C:\Test\Psjob.txt"
     'Start-Sleep'
     Start-Sleep (2*60)
     'Ready'
     Stop-Transcript
}
 
Main

When correctly executed this script will generate a transcript that looks like this:

**********************
Windows PowerShell Transcript Start
Start time: 20090305111600
Username  : DOMAIN\SYSTEM
Machine   : MACHINENAME (Microsoft Windows NT 5.2.3790 Service Pack 2)
**********************
Transcript started, output file is C:\Test\Psjob.txt
Start-Sleep
Ready
**********************
Windows PowerShell Transcript End
End time: 20090305111800
**********************

However, if I log off the console while the script is executing I get the following transcript:

**********************
Windows PowerShell Transcript Start
Start time: 20090305114300
Username  : DOMAIN\SYSTEM
Machine   : MACHINENAME (Microsoft Windows NT 5.2.3790 Service Pack 2)
**********************
Transcript started, output file is C:\Test\Psjob.txt
Start-Sleep
**********************
Windows PowerShell Transcript End
End time: 20090305114340
**********************

As you can see the transcript is properly ended as PowerShell shuts down, but if you look at the output in the middle you'll see that we never write "Ready" to the file. This is because the script was prematurely terminated.

Resolution

The quick and easy resolution is to upgrade to Vista, Windows Server 2008 or later, since as of Windows Vista the console session is no longer running in Session 0.