Powershell exit on any error



Handling Errors the PowerShell Way

Summary : Trevor Sullivan talks about handling errors in Windows PowerShell.

Microsoft Scripting Guy, Ed Wilson, is here. Today we have guest blogger and Windows PowerShell MVP, Trevor Sullivan… also find Trevor on Twitter ( https://twitter.com/pcgeek86 ) and his blog ( http://trevorsullivan.net )

Microsoft Scripting Guy, Ed Wilson, just wrote a post about how to use the Try-Catch-Finally blocks in Windows PowerShell. But have you ever wondered if that was the only way to handle errors? It turns out that although it’s a great way to handle errors, there are still other options!

If you’re coming to Windows PowerShell from a software development background, you’ll most likely pick up on Try-Catch-Finally pretty easily. On the other hand, if you’re new to scripting, or you are a curious, knowledge-driven individual, you might want to consider what we’re talking about today.

Common parameters

When Windows PowerShell 2.0 came out, a new concept was introduced, called Advanced Functions. This concept allows you to develop commands that have the same feel as compiled cmdlets, while writing them in Windows PowerShell script syntax. One of the benefits of developing cmdlet-style commands instead of basic functions, is that they offer a few “common parameters.” Two of these common parameters are related to error handling: -ErrorAction and -ErrorVariable.

For more information about common parameters in advanced functions and compiled cmdlets, run this command at the Windows PowerShell prompt:

Get-Help -Name about_CommonParameters;

Normally, if you run a Windows PowerShell command and an error occurs, the error record will be appended to the “automatic variable” named $error. When you use the -ErrorVariable parameter in a call to a command, the error is assigned to the variable name that you specify. It’s important to note that even when you use the -ErrorVariable parameter, the $error variable is still updated.

By default, the -ErrorVariable parameter will overwrite the variable with the name that you specify. If you want to append an error to the variable, instead of overwriting it, you can put a plus sign (+) in front of the variable name. Let’s take a look at an example:

Stop-Process -Name invalidprocess -ErrorVariable ProcessError;
$ProcessError;
Stop-Process -Name invalidprocess2 -ErrorVariable +ProcessError;
if ($ProcessError) <
######## Take administrative action on error state
>

ErrorAction parameter

The -ErrorAction common parameter allows you to specify which action to take if a command fails. The available options are: Stop, Continue, SilentlyContinue, Ignore, or Inquire. If you’re developing a Windows PowerShell workflow, you can also use the Suspend value. However, advanced functions cannot be suspended.

When you specify the ErrorAction parameter during a call to a command, the specified behavior will override the $ErrorActionPreference variable in Windows PowerShell. This variable is part of a handful of variables known as “preference variables.” By default, Windows PowerShell uses an error action preference of Continue, which means that errors will be written out to the host, but the script will continue to execute. Hence, these types of errors are known as “non-terminating” errors.

If you set $ErrorActionPreference to Stop or if you use Stop as the parameter value for -ErrorAction, Windows PowerShell will stop the script execution at the point an error occurs. When these errors occur, they are considered “terminating errors.”

As an example, if you want to stop the execution of your Windows PowerShell script when an error occurs during a call to Stop-Process, you can simply add the -ErrorAction parameter and use the value Stop:

Stop-Process -Name invalidprocess -ErrorAction Stop;

If you want to suppress the errors from being displayed, you can use the value SilentlyContinue, for example:

Stop-Process -Name invalidprocess -ErrorAction SilentlyContinue;

You can also combine the ErrorAction and ErrorVariable parameters, such as in this example:

Stop-Process –Name invalidprocess -ErrorAction SilentlyContinue -ErrorVariable ProcessError;

####### Something went wrong

We have explored the use of two Windows PowerShell common parameters, ErrorAction and ErrorVariable. I hope that this post has enlightened you about the use of these variables and how to use them to direct the execution flow of your scripts. Thank you for reading, and I will see you next time!

Источник

about_Try_Catch_Finally

Краткое описание

Описывает, как использовать блоки try , catch и finally для обработки неустранимых ошибок.

Читайте также:  Error no pduapi module found

Подробное описание

Используйте try блоки , catch и finally для реагирования или обработки неустранимых ошибок в скриптах. Оператор Trap также можно использовать для обработки неустранимых ошибок в скриптах. Дополнительные сведения см. в разделе about_Trap.

Неустранимая ошибка останавливает выполнение инструкции. Если PowerShell не обрабатывает неустранимую ошибку, PowerShell также прекращает выполнение функции или скрипта с помощью текущего конвейера. В других языках, таких как C#, устранимые ошибки называются исключениями.

try Используйте блок , чтобы определить раздел скрипта, в котором PowerShell будет отслеживать ошибки. При возникновении ошибки в блоке try она сначала сохраняется в автоматической переменной $Error . Затем PowerShell ищет блок для catch обработки ошибки. Если в инструкции try нет соответствующего catch блока, PowerShell продолжит поиск соответствующего catch блока или Trap оператора в родительских областях. После завершения блока или если соответствующий catch catch блок или Trap оператор не найден, finally блок выполняется. Если ошибка не может быть обработана, она записывается в поток ошибок.

Блок catch может включать команды для отслеживания ошибки или восстановления ожидаемого потока скрипта. Блок catch может указать типы ошибок, которые он перехватывает. Инструкция try может включать несколько catch блоков для различных типов ошибок.

Блок finally можно использовать для освобождения всех ресурсов, которые больше не нужны вашему скрипту.

try , catch и finally напоминают ключевые try слова , catch и finally , используемые на языке программирования C#.

Синтаксис

Оператор try содержит try блок, ноль или несколько catch блоков, а также ноль или один finally блок. Оператор должен иметь по крайней try мере один catch блок или один finally блок.

Ниже показан try синтаксис блока.

За try ключевым словом следует список операторов в фигурных скобках. Если во время выполнения инструкций в списке операторов возникает неустранимая ошибка, скрипт передает объект ошибки из блока в try соответствующий catch блок.

Ниже показан catch синтаксис блока.

Типы ошибок отображаются в квадратных скобках. Крайние квадратные скобки указывают, что элемент является необязательным.

За catch ключевым словом следует необязательный список спецификаций типов ошибок и список инструкций. Если в блоке try возникает неустранимая ошибка, PowerShell выполняет поиск соответствующего catch блока. Если он найден, выполняются операторы в catch блоке .

Блок catch может указывать один или несколько типов ошибок. Тип ошибки — это исключение платформа .NET Framework Майкрософт или исключение, которое является производным от платформа .NET Framework исключения. Блок catch обрабатывает ошибки указанного платформа .NET Framework класса исключений или любого класса, производного от указанного класса.

catch Если блок указывает тип ошибки, этот catch блок обрабатывает этот тип ошибки. catch Если блок не указывает тип ошибки, он catch обрабатывает все ошибки, возникшие в блоке try . Инструкция try может включать несколько catch блоков для различных указанных типов ошибок.

Ниже показан finally синтаксис блока.

За finally ключевым словом следует список инструкций, который выполняется каждый раз при выполнении скрипта, даже если try инструкция выполнялась без ошибок или в инструкции была обнаружена catch ошибка.

Обратите внимание, что нажатие клавиши CTRL + C останавливает конвейер. Объекты, отправляемые в конвейер, не будут отображаться в качестве выходных данных. Таким образом, если включить отображаемую инструкцию, например «Finally block has run», она не будет отображаться после нажатия клавиш CTRL + C , даже если finally блок запущен.

выявления ошибок;

В следующем примере скрипта try показан блок с блоком catch :

Ключевое catch слово должно немедленно следовать за блоком try или другим блоком catch .

PowerShell не распознает «NonsenseString» как командлет или другой элемент. Выполнение этого скрипта возвращает следующий результат:

Когда скрипт обнаруживает «NonsenseString», это приводит к неустранимой ошибке. Блок catch обрабатывает ошибку, выполняя список инструкций внутри блока.

Использование нескольких операторов catch

Инструкция try может содержать любое количество catch блоков. Например, следующий скрипт имеет try блок, который загружает MyDoc.doc , и содержит два catch блока:

Первый catch блок обрабатывает ошибки типов System.Net.WebException и System.IO.IOException . Во втором catch блоке не указан тип ошибки. Второй catch блок обрабатывает любые другие неустранимые ошибки.

PowerShell сопоставляет типы ошибок по наследованию. Блок catch обрабатывает ошибки указанного платформа .NET Framework класса исключений или любого класса, производного от указанного класса. В следующем примере содержится catch блок, который перехватывает ошибку «Command Not Found» (Команда не найдена):

Указанный тип ошибки CommandNotFoundException наследуется от типа System.SystemException . В следующем примере также обнаруживается ошибка Command Not Found ( Команда не найдена):

Читайте также:  Error parse error expected http

Этот catch блок обрабатывает ошибку «Команда не найдена» и другие ошибки, которые наследуются от типа SystemException .

Если указан класс ошибок и один из его производных классов, поместите catch блок для производного класса перед блоком catch для общего класса.

PowerShell создает оболочку для всех исключений в тип RuntimeException . Таким образом, указание типа ошибки System.Management.Automation.RuntimeException ведет себя так же, как неквалифицированный блок catch.

Использование ловушек в пробном перехвате

При возникновении неустранимой ошибки в try блоке с Trap определенным в try блоке , даже при наличии соответствующего catch блока оператор Trap берет на себя управление.

Если объект существует в блоке выше , чем try , и в текущей Trap области нет соответствующего catch блока, Trap объект будет принимать управление, даже если любая родительская область имеет соответствующий catch блок.

Доступ к сведениям об исключении

В блоке catch доступ к текущей ошибке можно получить с помощью $_ , который также называется $PSItem . Объект имеет тип ErrorRecord.

Выполнение этого скрипта возвращает следующий результат:

Доступны дополнительные свойства, например ScriptStackTrace, Exception и ErrorDetails. Например, если мы изменим скрипт на следующий:

Результат будет выглядеть примерно так:

Освобождение ресурсов с помощью finally

Чтобы освободить ресурсы, используемые скриптом, добавьте finally блок после try блоков и catch . Инструкции finally block выполняются независимо от того, возникает ли try в блоке неустранимая ошибка. PowerShell запускает finally блок до завершения скрипта или до выхода текущего блока за пределы области действия.

Блок finally выполняется, даже если для остановки скрипта используется клавиша CTRL + C . Блок finally также запускается, если ключевое слово Exit останавливает скрипт из catch блока.

Источник

Powershell exit on any error

This forum has migrated to Microsoft Q&A. Visit Microsoft Q&A to post new questions.

Answered by:

Question

What is the «best practice» to stop your PowerShell module on error but still respect the calling script $ErrorActionPreference?

User script «Run.ps1»:

This will stop the module execution on error as needed, but also stop the «user script» Run.ps1 overriding his ErrorActionPreference so ‘RUN THIS (Not part of the module)’ will not run which is not desirable.

Can I use «$ErrorActionPreference = ‘Stop'» or «-ErrorAction Stop» inside the module without braking the user script? separating the user script and the module «Scope» in some way maybe?
Or do I have to use «try. catch» and «Return» combination instead?

Answers

Just to update this old topic with a «Solution»

A few months ago an Issues was open on the PowerShell GitHub that provides a good explanation and some fixes suggestions.

In short it describe the differences between the 3 PowerShell error types (Yes 3 types not 2)

  • Non-terminating errors (Write-Error)
  • Script-terminating errors (Cmdlets, .NET exceptions)
  • Statement-terminating errors (Throw , Write-Error ‘With’ -ErrorAction Stop )

Also see the section of «Reporting custom errors in functions and scripts» and the $PSCmdlet.ThrowTerminatingError() option.

All replies

ErrorActionPref = Stop only works on the currently executing command. It will stop the command and go to the next line always.

See: help about_try_catch

ErrorActionPref = Stop only works on the currently executing command. It will stop the command and go to the next line always.

See: help about_try_catch

I’m not understanding what you are trying to say

about_Try_Catch_Finally has noting to do with $ErrorActionPreference that’s in about_Preference_Variables, and anyway it’s not answering my question.

I am saying that what you are asking cannot be done as asked. You need to use Try/Catch to catch an exception and take the steps you need to take.

First learn how to use PowerShell and how errors and exceptions are managed in code. Until you understand that you will not be able to understand my answer.

I am saying that what you are asking cannot be done as asked. You need to use Try/Catch to catch an exception and take the steps you need to take.

First learn how to use PowerShell and how errors and exceptions are managed in code. Until you understand that you will not be able to understand my answer.

Your previous answer is just wrong, and if not please explain why.
«$ErrorActionPreference = ‘Stop'» will not «stop the command and go to the next line always» it will stop the script execution as it will treat any non-terminating error as terminating error and terminate.
«-ErrorAction Stop» will override $ErrorActionPreference for the specific cmdlet/Function

Читайте также:  Protocol error code 404

So you say that in order to properly address this the only option is to use «Try/Catch» and «Return» like this?

Not how it works. It will terminate each command and move to the next command.

Try/Catch will let you catch the error and terminate to the «Catch» block where you can decide what to do next. If you want to terminate the script in the «Catch» block then use «exit» and PowerShell session will exit.

$ErrorActionPreference just changes the default form «Continue» to «Stop» for all CmdLets.

Believe me. It will not terminate a script.

Using Try/Catch in your example function is the way to skip the remainder of the code in the «Try» block.

A little food for thought.

Exception handling has been around for 30+ years. See this.

Most languages have full time exception handling. PowerShell has it turned off by default by using «Continue». It is really not turned off but is handled by displaying the exception and adding it to the error stack «$error»

Here is the reference for Try/Catch/Finally — https://en.wikipedia.org/wiki/Exception_handling_syntax including a lsit of the langugaes that use it.

Its behavior is nearly identical in all languages

It’s will not move to the next command.

Run this script and tell me if the last line is executing and you see «This will never run» on your console

Also «Exit» will terminate the user script not only the module this is why I used «Return»

In all cases you cannot stop the throwing of an exception. You can only alter what happens after it is «thrown» . «Write-Error» «throws» an exception.

Note: Changing ErrorActionPreference doe no stop errors it only hides the message on the screen or cause the exception to be available to Try/Catch.

Exceptions cannot be disabled. They will always end up in $error.

You are just typing commands after another, you are not running it as a continues .ps1 script or a script block

You were asking bout global preference.

In scripts and functions it works like this:

You’re really in a trolling mood today aren’t you? (:

Don’t know what that means.

I have a feeling that I do not understand what it is you are asking. Can you clarify what your issue is? What is not happening or what is happening that you do not expect?

In case you haven’t already discovered this here is another and, perhaps, better way to control how a script handles script level (or function) error actions.

Then you can run it like this:

.\teste.ps1
.\teste.ps1 -ErrorAction stop
.\teste.ps1 -ErrorAction SilentlyContinue

Your question still baffle me. Perhaps it is a language issue.

You asked: «Stopping Module on error without breaking calling script»

What «module» are you referring to? «Modules» do not run they just load. If a function resides in a module and it throws an exception it would not, under normal settings, stop the calling script.

We generally don’t use global preference settings as they can cause odd behaviors in many CmdLet. It is better to use individual CmdLet «ErrorAction» parameter. We also don’t generally use «Stop» unless we are going to use a Try/Catch block to catch the exception and act on it.

There is a spec that lays out what is called «Structured Exception Handling» (SEH) that specifies how this is intended to work. Microsoft mostly complies to this spec which describes how we handle and «bubble» errors from lower layers of code bac to upper layers. «Stop» in PowerShell always disables any bubbling and assumes the exception will be handled locally. To react to an error and bubble using «Stop» we would «re-throw the exception in the «Catch» block.

Try<
# code that can throw an exxception
. more lines
>
Catch<
Throw $_ # rethrow exception to outer calling code block
return
>

Источник

Оцените статью
toolgir.ru
Adblock
detector