Mysteries of trapping errors in PowerShell

As everyone in IT knows, sometimes tasks that you think are quick and easy turn out to take longer.

Today I experiences a small example. I have a scheduled PowerShell script that copies a large file. I wanted to enhance the script so that I would receive an email stating whether the copy succeeded and when it completed.

The original script, for the sake of the example (it is actually a little more involved) is this:

Copy-Item somefile somefile.bak

"Clean up"

where “Clean up” represents some code that runs after the copy completes.

Now, by default a PowerShell may continue if it hits an error other than a syntax error. Again for the sake of the example, I will add a line which echoes text to represent the code that send an email. If you run this script:

Copy-Item somefile somefile.bak

"Clean up"

”Send email: File copied successfully”

then the email gets sent whether or not the copy succeeds. Here is what happens if somefile does not exist:

image

Not much use. The solution, I thought, was to use PowerShell’s trap statement. This catches the exception you specify, or all exceptions, and runs some code. You can also use the break or continue keywords to determine whether the block of code in which the exception occurred continues with the next statement, or exits immediately. You can read about trap here. I therefore wrote a script that looks like this:

Function CopyIt {

trap {return "Error copying file: $_"; break;}

Copy-Item somefile somefile.bak

return "Copy successfully completed"

}

$result = CopyIt

"Clean up"

”Send email: $result”

What I could not figure out though was that even when the copy failed, the script still sent me a success message:

image

I assumed I was misunderstanding how trap works. The output shows, in this example, that an ItemNotFoundException is thrown, so the trap should be triggered, right?

Wrong. In the case of non-terminating errors  (PowerShell jargon) you have to specify the ErrorAction. The default ErrorAction is “Continue”. Therefore I had to modify the script like this:

Copy-Item somefile somefile.bak -ErrorAction stop

Now I get an email with a failure message if the copy fails:

image

All very obvious to PowerShell experts; but it seems to me that PowerShell makes it easy for the unwary to write scripts that fail silently. You are unlikely to see the red text when your script is running on a server.

Page 1 of 2 | Next page

Related posts:

  1. Installing .NET, PowerShell on Windows 2008 Server Core: it can be done
  2. Security errors when developing for Windows Mobile