Lessons In PowerShell - Logging From A Script Running Via Windows Task Scheduler

   Submit to Reddit      
  

Logging and tracing information can normally be written to the host console, standard output or standard error streams. However, when a PowerShell script is run from the Windows Task Scheduler, those mechanisms are typically not available.

To work around this situation, I decided to create a log file for my PowerShell Script which is executed from Windows Task Scheduler.

For a start, we can use the .NET StreamWriter class to create a file stream.

$logFile = New-Object System.IO.StreamWriter("C:\temp\Script.log")

Please note: you must ensure that the user account the script runs under needs to have file system security access to that specific folder and file.

We can then create a function that will write a message to the log file and also flush the stream (I wanted to closely monitor the progress of the script while it may be running, so I am explicitly flushing the stream).

Function LogMessage($message)
{
    $logFile.WriteLine($message)

    $logFile.Flush()
}

And using the mimicked PowerShell Version 1 Try / Catch / Finally script block, we can ensure that even if an error occurs, the stream will be closed. See the bottom line below.

Here is the script in its entirety.

# Trap settings
$ReportErrorShowExceptionClass=$true
$ReportErrorShowInnerException=$true
$ReportErrorShowSource=$true
$ReportErrorShowStackTrace=$true

# Setup log file functionality
$now=Get-Date
$logFile = New-Object System.IO.StreamWriter("C:\temp\Script.log")

Function LogMessage($message)
{
    $logFile.WriteLine($message)
    $logFile.Flush()
}

&{
    &{ #Try 
          LogMessage("Started at " + $now)
          ...
          LogMessage("Successfully finished")
    } 
    trap #Catch
    {
        LogMessage("TRAPPED: " + $_.Exception.GetType().FullName) 
        LogMessage("TRAPPED: " + $_.Exception.Message)
        continue # So that the "Finally" gets executed
    }
} #Finally
$logFile.Close()

There we have it... a PowerShell script that runs under Windows Task Scheduler and writes out to a log file.

Of course, using the PowerShell Version 2 Try/Catch statement is much nicer than this PowerShell Version 1 equivalent.

Lessons In PowerShell - Calling A Static / Shared Method

   Submit to Reddit      
  

In order to call a static / shared .NET method from PowerShell, use the following format.

Format:

[type]::StaticMethodName

Example:

[DateTime]::Now

Note: In this specific example, the PowerShell alias Get-Date could be used instead of [DateTime]::Now � this is just an example!

Lessons In PowerShell - Running a PowerShell Script Via Windows Task Scheduler

   Submit to Reddit      
  

In order to run a Windows PowerShell script through the Windows Task Scheduler:

  • Run the Task Scheduler:

    Start ➞ Control Panel ➞ Administrative Tools ➞ Task Scheduler

  • Create and schedule a task that starts a program.

    Specify the program to run as:

      C:\WINDOWS\system32\WindowsPowerShell\v1.0\Powershell.exe
    

    Specify the arguments as:

      C:\PathToMyScript\MyScript.ps1
    

The PowerShell script will now run as scheduled.

Lessons In PowerShell - Exception Handling

   Submit to Reddit      
  

The following useful information is primarily taken from the Windows PowerShell Language Quick Reference (QuadFold.rtf) documentation.

Throw

The keyword "Throw" allows an exception to be thrown. The argument for the Throw keyword can be a string, exception or ErrorRecord.

throw "Some description about the exception"

Traps

A trap is a mechanism to catch an exception, although it behave more like the Visual Basic 6 On Error functionality. The continue keyword will continue execution at the script statement after the one that caused the trap. $? is updated but no error record is generated. The break keyword will rethrow the exception.

Trap [ExceptionType] 
{
    if (...) 
    { 
        continue
    } else (...)
    { 
        break
    }

    # Doing nothing will do what is specified in the $ErrorActionPreference setting
}

Try / Catch / Finally

There is no native support in PowerShell Version 1 for the typical Try / Catch / Finally syntax found in other languages. However with the use of the & invoke operator, the Try / Catch / Finally syntax can be mimicked.

&{
     &{   # Try
          # Do your processing here
     } 
     trap # Catch
     {
         Write-Host "TRAPPED: " + $_.Exception.GetType().FullName
         Write-Host "TRAPPED: " + $_.Exception.Message
         continue   # So that the "Finally" stuff gets executed
     }
} #Finally
# Put your finally code here

However, from PowerShell Version 2, you can use the familiar try / catch syntax.

    try {
        ...
    } catch {
        ...
    }