Powershell: How can I stop errors from being displ

2019-01-22 00:52发布

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?

5条回答
迷人小祖宗
2楼-- · 2019-01-22 01:20

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.

查看更多
走好不送
3楼-- · 2019-01-22 01:25

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.

查看更多
做自己的国王
4楼-- · 2019-01-22 01:32

If you want the powershell errormessage for a cmdlet suppressed, but still want to catch the error, use "-erroraction 'silentlyStop'"

查看更多
Summer. ? 凉城
5楼-- · 2019-01-22 01:34

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.

查看更多
放荡不羁爱自由
6楼-- · 2019-01-22 01:42

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)
        }
}
查看更多
登录 后发表回答