-ErrorAction

vbserror 

Итак, вторую тему про работу с ошибками в PowerShell я решил посвятить параметру -ErrorAction. Этот параметр является «Common», то есть автоматически присутствует во всех командлетах, даже если автор ничего для этого не сделал (правда для того чтобы он работал правильно автору придется всё таки приложить некоторые усилия😉 )

Именно параметр -ErrorAction позволяет задать действие выполняемое при возникновении ошибки.

Вывести сообщение об ошибке и продолжить выполнение — «Continue»

Молча проигнорировать ошибку и продолжить — «SilentlyContinue»

При первой же ошибке прервать выполнение — «Stop»

При возникновении ошибки вывести запрос что делать дальше — «Inquire»

Для наглядности покажу всё на примерах. В каталоге test я поместил два файла — file1.txt и file2.txt.

 

Continue

Сначала укажем в качестве аргумента -ErrorAction «Continue»:

[PS <103> C:\…\test] "file1.txt","file2.txt","file3.txt" | Get-Item -ErrorAction "Continue"

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Root\test

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07.04.2008     10:23          3 file1.txt
Get-Item : Cannot find path 'C:\Root\test\file2.txt' because it does not exist.
At line:1 char:47
+ "file1.txt","file2.txt","file3.txt" | Get-Item <<<<  -ErrorAction "Continue"
-a---        07.04.2008     10:23          3 file3.txt

Как и ожидалось, при обработке «file2.txt» (которого не существует) была выдана ошибка, но тем не менее выполнение было продолжено.

 

SilentlyContinue

Что если нам не критично наличие этого файла, и ошибку мы видеть не хотим?

[PS <104> C:\…\test] "file1.txt","file2.txt","file3.txt" | Get-Item -ErrorAction "SilentlyContinue"

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Root\test

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07.04.2008     10:23          3 file1.txt
-a---        07.04.2008     10:23          3 file3.txt

Get-Item молча проглотив обиду ошибку, продолжил делать свою работу😉

 

Stop

А теперь представим что наличие всех указанных файлов нам наоборот критично для дальнейшей работы, и если хоть один отсутствует — следует прервать обработку:

[PS <105> C:\…\test] "file1.txt","file2.txt","file3.txt" | Get-Item -ErrorAction "Stop"

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Root\test

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07.04.2008     10:23          3 file1.txt
Get-Item : Command execution stopped because the shell variable "ErrorActionPreference" is set 
to Stop: Cannot find path 'C:\Root\test\file2.txt' because it does not exist.
At line:1 char:47
+ "file1.txt","file2.txt","file3.txt" | Get-Item <<<<  -ErrorAction "Stop"

Итак на этот раз после возникновения первой же ошибки работа была прервана, и файл «file3.txt» не был обработан.

 

Inquire

Ну и последний вариант, как уже было описано выше — выдаст запрос:

[PS <106> C:\…\test] "file1.txt","file2.txt","file3.txt" | Get-Item -ErrorAction "Inquire"

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\Root\test

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        07.04.2008     10:23          3 file1.txt

Confirm
Cannot find path 'C:\Root\test\file2.txt' because it does not exist.
[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"):

В данном случае Yes — будет означать «Продолжить», «Yes to All» — продолжить выполнение несмотря на эту и все последующие ошибки, «Halt command» — соответственно прервет выполнение. Самый интересный пункт тут, это «Suspend». Выбрав его вы попадёте в так называемый «Nested namespace» (не знаю как красиво перевести на русский😦 ). По сути это полноценный дочерний процесс, в котором можно выполнять команды, запускать скрипты, и делать практически всё тоже что и в основной консоли. Например я проверил наличие test2.txt (удивительно! его и правда нет!😉 ), и вышел из вложенного namespace вернувшись к тому же сообщению, в котором на этот раз выбрал опцию Halt

[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): s
[PS <107> (1) C:\…\test] Test-Path file2.txt
False
[PS <108> (1) C:\…\test] exit

Confirm
Cannot find path 'C:\Root\test\file2.txt' because it does not exist.
[Y] Yes  [A] Yes to All  [H] Halt Command  [S] Suspend  [?] Help (default is "Y"): h
Get-Item : Command execution stopped because the user selected the Halt option.
At line:1 char:47
+ "file1.txt","file2.txt","file3.txt" | Get-Item <<<<  -ErrorAction "Inquire"

Может возникнуть вопрос — что же происходит если не указывать параметр -ErrorAction? А всё просто — будет взято значение специальной переменной $ErrorActionPreference, по умолчанию оно равно «Continue».

 

Полезные советы

№1: Если вы забыли названия различных аргументов для -ErrorAction, то можно просто выполнить любую команду указав после -ErrorAction какую нибудь билеберду. В тексте ошибки будут перечислены правильные варианты:

[PS <111> C:\…\test] Get-Item -ErrorAction билеберда
Get-Item : Cannot bind parameter 'ErrorAction'. Cannot convert value "билеберда" to type "System.Management.Automation.
ActionPreference" due to invalid enumeration values. Specify one of the following enumeration values and try again. The
 possible enumeration values are "SilentlyContinue, Stop, Continue, Inquire".
At line:1 char:22
+ Get-Item -ErrorAction <<<<  билеберда

№2: У параметра -ErrorAction есть псевдоним (да, в PowerShell псевдонимы могут быть даже у параметров🙂 ), для того чтобы лентяи типа меня могли экономить несколько нажатий клавиш: -EA. Кроме того, так как аргументы в итоге всё равно преобразовываются в перечисление (enum), а все значения перечислений на самом деле являются числами, то можно указывать сразу числовые значения: SilentlyContinue = 0, Stop = 1, Continue = 2, Inquire = 3. В итоге вместо -ErrorAction «SilentlyContinue» пишем просто -EA 0😉

UPD: Я специально не стал останавливаться на вложенных шеллах (параметр Suspend). Эта тема заслуживает как минимум отдельного поста.

комментариев 5 to “-ErrorAction”

  1. PowerShell и другие скрипты : -ErrorAction Says:

    […]   Итак, вторую тему про работу с ошибками в PowerShell я решил посвятить параметру -ErrorAction. Этот параметр является “Common”, то есть автоматически присутствует во всех командлетах, даже если автор ничего для этого не сделал (правда для того чтобы он работал правильно автору придется всё таки приложить некоторые усилия ) Именно параметр -ErrorAction позволяет задать действие выполняемое при возникновении ошибки. Читать далее… […]

  2. s7s Says:

    Пробывал применить данный урок, ничего не получилось

    Мне нужно получить список каталогов/файлов и права пользователей на эти русурсы. Делаю это так:

    get-childitem q:\ -recurse | get-acl | format-table -wrap -autosize

    Сам не являюсь владельцем всех папок и нет к ним доступа, вледствии чего получаю ошибку. И пропустить ее никак не получаеться. Поскажите как это можно реализовать?

  3. Xaegr Says:

    2 s7s: Интересная ошибка. Мне кажется она происходит на слишком низком уровне… Получилось обойти таким образом:
    $ErrorActionPreference = «SilentlyContinue»
    dir c:\Users | foreach {$_ | get-acl} | ft -Wrap -Auto

  4. s7s Says:

    Данный способ также не принес результатов.
    Самое интересное, что если я пишу

    get-childitem q:\dir2 | get-acl -ErrorAction «SilentlyContinue» | format-table -wrap -autosize

    тогда ошибка НЕ вылезает (dir2 — это каталог, где у меня нет доступов)

    если же пытаюсь проделать тоже самое для q:\, тогда dir1, срабатывает нормально, там у меня есть доступ, а вот на dir2 затыкаеться.

    Будут соображения по этому поводу?

  5. Xaegr Says:

    Сообщил о проблеме — https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=66336&SiteID=99
    Можно проголосовать для повышения рейтинга баги, и скорейшего исправления🙂


Обсуждение закрыто.

%d такие блоггеры, как: