When my PowerShell script tries, for example, to create a SQL Server object for a server that doesn't exist ("bla" in my case), PowerShell displays lots of PowerShell errors in red.
Since my script checks the value of $?
after such calls, and displays and logs errors, I'd rather not have the several lines of PowerShell errors displayed as well.
How can I deactivate those being displayed for my script?
You have a couple of options. The easiest involve using the ErrorAction
settings.
-Erroraction
is a universal parameter for all cmdlets. If there are special commands you want to ignore you can use -erroraction 'silentlycontinue'
which will basically ignore all error messages generated by that command. You can also use the Ignore
value (in PowerShell 3+):
Unlike SilentlyContinue, Ignore does not add the error message to the $Error automatic variable.
If you want to ignore all errors in a script, you can use the system variable $ErrorActionPreference
and do the same thing: $ErrorActionPreference= 'silentlycontinue'
See about_CommonParameters for more info about -ErrorAction.
See about_preference_variables for more info about $ErrorActionPreference.
Windows PowerShell provides two mechanisms for reporting errors: one mechanism for terminating errors and another mechanism for non-terminating errors.
Internal CmdLets code can call a ThrowTerminatingError
method when an error occurs that does not or should not allow the cmdlet to continue to process its input objects. The script writter can them use exception to catch these error.
EX :
try
{
Your database code
}
catch
{
Error reporting/logging
}
Internal CmdLets code can call a WriteError
method to report non-terminating errors when the cmdlet can continue processing the input objects. The script writer can then use -ErrorAction option to hide the messages, or use the $ErrorActionPreference
to setup the entire script behaviour.
I had a similar problem when trying to resolve host names using [system.net.dns]
. If the IP wasn't resolved .Net threw a terminating error.
To prevent the terminating error and still retain control of the output, I created a function using TRAP
.
E.G.
Function Get-IP
{PARAM ([string]$HostName="")
PROCESS {TRAP
{"" ;continue}
[system.net.dns]::gethostaddresses($HostName)
}
}
You're doing it wrong.
You already have a nice, big error message. Why on Earth would you want to write code that checks $?
explicitly after every single command? This is enormously cumbersome and error prone. The correct solution is stop checking $?
.
Instead, use PowerShell's built in mechanism to blow up for you. You enable it by setting the error preference to the highest level:
$ErrorActionPreference = 'Stop'
I put this at the top of every single script I ever write, and now I don't have to check $?
. This makes my code vastly simpler and more reliable.
If you run into situations where you really need to disable this behavior, you can either catch
the error or pass a setting to a particular function using the common -ErrorAction
. In your case, you probably want your process to stop on the first error, catch the error, and then log it.
Do note that this doesn't handle the case when external executables fail (exit code nonzero, conventionally), so you do still need to check $LASTEXITCODE
if you invoke any. Despite this limitation, the setting still saves a lot of code and effort.
Additional reliability
You might also want to consider using strict mode:
Set-StrictMode -Version Latest
This prevents PowerShell from silently proceeding when you use a non-existent variable and in other weird situations. (See the -Version
parameter for details about what it restricts.)
Combining these two settings makes PowerShell much more of fail-fast language, which makes programming in it vastly easier.
If you want the powershell errormessage for a cmdlet suppressed, but still want to catch the error, use "-erroraction 'silentlyStop'"