4

I have some powershell scripts with the following in them:

$ErrorActionPreference = "stop"
trap { Write-Error $_.Exception; }

When calling the script from a powershell window using a powershell redirection operator:

c:\somescript.ps1 2> c:\error.txt

It will only print out the error to the powershell window and not redirect it to the file. If I remove $ErrorActionPreference = "stop" from the script, then the redirection works, but that isn't a viable option since we need the scripts to terminate if it runs into any error. I've tried using '*>' too, but that produces the same results.

Is there any way to redirect the errors to a file without having to change all the scripts?

qwert1234
  • 128
  • 10

2 Answers2

5

The problem with your approach is that $ErrorActionPreference = "Stop":

  • instantly stops (aborts) the entire script and the command that calls it, c:\somescript.ps1 2> c:\error.txt,

  • which means that the redirection 2> c:\error.txt is not performed, and the error message displays in the console rather than being captured in the specified file.

The workaround is somewhat cumbersome:

Wrap the invocation of the other script in a try ... catch statement as follows:Tip of the hat to FatalBulletHit for his help.

$ErrorActionPreference = 'Stop'

try {

 c:\somescript.ps1

} catch {

  # Now you can write the error record to the file.
  $_ > c:\error.txt

  # == Optional additional actions.

  # If desired, you can additionally 
  # emit the error too (write it the error to the error stream).
  # !! -ErrorAction Continue is necessary in order to override
  # !! $ErrorActionPreference = 'Stop'.
  # !! Without it, the use of Write-Error itself would cause an - uncaught -
  # !! script-terminating (fatal) error. 
  Write-Error -ErrorRecord $_ -ErrorAction Continue

  # Exit the script with a nonzero exit code to signal failure
  # (which is useful if your script is called from *outside*
  # PowerShell).
  exit 1

}

The need to use -ErrorAction Continue (or temporarily set $ErrorActionPreference = 'Continue') before calling Write-Error in the catch block to avoid causing a script-terminating (fatal) error is surprising; it would also apply if your script / function is an advanced one and you used $PSCmdlet.WriteError($_) instead.

mklement0
  • 382,024
  • 64
  • 607
  • 775
0

You might want to have a look at using Try Catch Finally for Error Trapping.

I have had the most success with that.

Great TechNet Blog on this subject

Lachie White
  • 1,246
  • 2
  • 14
  • 21
  • While this link _may_ answer the question, it is better to include the essential parts _here_ and provide the link only for reference / additional information. (Mostly) link-only answers can become invalid if the linked page changes. – mklement0 Dec 14 '16 at 19:44
  • 1
    Agreed, i am sorry about that. Was going to come back through today and add some code behind it. As mklement0 has now down almost exactly what i was going to there is no need! – Lachie White Dec 14 '16 at 23:11