Home > Blockchain >  PowerShell, tell a script to output all errors to a text file
PowerShell, tell a script to output all errors to a text file

Time:11-05

I have a PowerShell script that is the startup script for Windows Sandbox and so it runs silently.

Is it possible to put some kind of declaration within a PowerShell script, say at the start of the script, that tells the silently running script to output all of its errors to a text file?

Edit (for Fitzgery's comment): it is not possible for me to use redirection for the script because it is running silently as part of the Windows Sandbox startup. I would like something within the script itself to instruct the running script to output all errors to a text file.

CodePudding user response:

Try the following, which relies on the fact that all errors that occur in a session get recorded in the automatic $Error variable:

$Error.Clear() # Reset the session's error log so far

try {

  # ... your script

} finally {
  # Save all errors that occurred in this script to a file.
  $Error > errors.txt
}

Caveat:

  • The use of a try statement has a side effect:

    • Your script may terminate prematurely, because any normally only statement-terminating error becomes a script-terminating error and therefore instantly triggers the finally clause; that said, statement-terminating errors aren't common, and it's arguably better to abort execution when they occur (unanticipated).
  • If you were to omit the try statement and simply placed $Error > errors.txt at the end of your script, (non-terminating and) statement-terminating errors would be handled as usual, but the $Error > errors.txt statement would never get to execute if a script-terminating error occurred.


An alternative solution using trap is side effect-free only if you know your script not to produce script-terminating errors:

  • Script-terminating errors are those explicitly created with throw, or implicitly via -ErrorAction Stop or $ErrorActionPreference = 'Stop'

  • The (rarely used anymore) trap statement allows you to act on errors without stopping execution, namely if you do not use break in the script block you pass to it.

    • While it therefore continues after non-terminating and statement-terminating errors, as during normal execution, it also continues after script-terminating ones.

    • Therefore, the side effect - if you script does create script-terminating errors, is that it may not stop your script when you expect it to.

# Create or truncate the target file.
$errLogFile = New-Item errors.txt -Force

# Traps all errors and logs them in the target ffile.
# Note:
#  * Using neither `break` or `continue` in the script block
#    still also prints the error and continues execution.
#  * CAVEAT: Even *script*-terminating errors then
#            do NOT abort execution.
trap { $_ >> $errLogFile }

# ... your script 

Use of Start-Transcript:

  • Start-Transcript is an way to capture all of a script's output, not just errors (that is, output from all of PowerShell's output streams is logged, notably including success output (data) - you get no choice).

  • It must be paired with Stop-Transcript to close the transcript file.

    • If you neglect to call Stop-Transcript, the transcript stays open and continues logging for the remainder of the session.

    • In order to ensure that Stop-Transcript is called, you're faced with the same tradeoffs as above:

      • Calling it in the finally block of a try statement may abort execution prematurely.
      • Use of a trap statement without break may not stop execution when it should.
    • That said, if the execution of your script is the only thing happens in your session - such as in a CLI call with -File - not calling Stop-Transcript won't be a problem, and ensures side effect-free logging - albeit invariably including all of the script's output, as noted.

  • Related