Reputation: 128
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?
Upvotes: 4
Views: 1488
Reputation: 439347
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.
Upvotes: 5
Reputation: 1261
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
Upvotes: 0