Reputation: 4050
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.
Upvotes: 3
Views: 2155
Reputation: 437111
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:
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:
finally
block of a try
statement may abort execution prematurely.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.
Upvotes: 3