Можно ли настроить $ ErrorActionPreference = 'Stop' по умолчанию для всех функций в модуле powershell? - PullRequest
1 голос
/ 25 апреля 2019

Я хочу, чтобы все функции в моем модуле по умолчанию были $ErrorActionPreference = 'Stop'. Возможно ли это без изменения всех функций?

У меня есть файл для каждой функции.

Ответы [ 2 ]

1 голос
/ 25 апреля 2019

Предполагается, что ваш модуль представляет собой модуль script , т.е. реализован в коде PowerShell:

Важно :

  • Модули имеют собственный стек областей, который не зависит от областей немодульного кода (и других модулей).Хотя это обеспечивает изоляцию от среды вызывающего, что обычно полезно, это также означает, что значение вызывающего абонента $ErrorActionPreference значение никогда не вступает в силу для функций модуля скрипта (если вы не запускаете напрямую из области действия global , которую также видят модули), - но это происходит для скомпилированных командлетов .Это очень проблемное поведение обсуждается в этой проблеме GitHub .

  • Даже если вы в настоящее время не можете контролировать поведение ошибки модуля скрипта из вызывающей стороны посредством $ErrorActionPreference, установив (переопределяя) $ErrorActionPreference в вашем модуле , вы закрываете эту дверь навсегда.

  • Однако, используя -ErrorAction общий параметр для конкретного вызова вместо $ErrorActionPreference предпочтительной переменной по-прежнему переопределяет глобальное значение $ErrorActionPreference вашего модуля, потому что за кулисами PowerShell переводит -ErrorAction аргумент локальной функции $ErrorActionPreference с этим значением.

  • Механизмы -ErrorAction и $ErrorActionPreference страдают от несоответствий и непонятного поведения - эта проблема с документацией по GitHub содержит подробный обзор обработки ошибок PowerShell.

Я хочу, чтобы все функции в моем модуле по умолчанию имели значение $ErrorActionPreference = 'Stop'.Возможно ли это без изменения всех функций?

Да - просто поместите $ErrorActionPreference = 'Stop' в код верхнего уровня вашего RootModule *.psm1 файла.(Запись RootModule файла манифеста модуля (*.psd1) указывает основной модуль модуля - см. документы ).

  • Если у вас нет RootModule запись, которая ссылается на файл .psm1, просто создайте файл .psm1 в папке вашего модуля (обычно называемый для включающего модуля) с содержимым $ErrorActionPreference = 'Stop', и обратитесь к нему из записи RootModule - см. этот ответ для справочной информации.

Если только он не перезаписывается вызывающим абонентом при использовании общего параметра -ErrorAction при вызове функций вашего модуля (при условии, что они являются advanced functions),Значение верхнего уровня $ErrorActionPreference вашего модуля будет действовать для всех функций вашего модуля, , кроме , если ваша функция напрямую испускает оператор , определяющий ошибку [1] , в этом случае значение $ErrorActionPreference вызывающего абонента имеет значение *1101* *1102*.


Если ваш модуль является двоичным модуль, т.е. экспортирует скомпилированные командлеты (обычно подразумеваетсясм. в C #):

Скомпилированные командлеты не имеют своей собственной области видимости - они работают в области вызывающей стороны .Поэтому $ErrorActionPreference вызывающего абонента имеет значение, которое может быть переопределено для каждого вызова с общим параметром -ErrorAction, но только для не ошибок, определяющих *. 1122*

Как и в случае с расширенными функциями в скриптовых модулях, [1] определяет ошибки *1124* [1] *1127* * всегда в зависимости от значения $ErrorActionPreference вызывающего,даже если -ErrorAction используется.(Обратите внимание, что двоичные командлеты не генерируют ошибки, определяющие script ).


[1] Оператор , определяющие ошибки, возникают в следующих сценариях:

  • Непосредственно , чтобы прервать выполнение включающего командлета или расширенной функции / сценария:

    • Когда двоичный командлет обнаруживает серьезную ошибку, которая не позволяет ему продолжить работу, он сообщает о такой ошибке с помощью метода ThrowTerminatingError() (или просто выдает исключение).

    • Для продвинутой функции / скрипта PowerShell также потребуется использовать $PSCmdlet.ThrowTerminatingError(), что, однако, редко встречается на практике;вместо этого обычно используемый оператор Throw создает ошибку, определяющую сценарий script , которая по умолчанию также завершает весь поток, т. е. также завершает вызывающую и все вызывающие ее стороны.

  • Косвенно в коде PowerShell:

    • Когда выражение вызывает время выполнения ошибка, например 1 / 0 или 'a,b' -split ',', 'NotAnInt'.

    • Когда при вызове метода .NET возникает исключение, например [int]::Parse('NotAnInt')

    • Когда внутри расширенной функции / сценария вызывается другой командлет или расширенная функция / сценарий, который непосредственно выдает ошибку завершения оператора.

    • Обратите внимание, что расширенные функции / сценарии не могут ретранслировать ошибки завершения операторов как таковые :

      • По умолчанию (с $ErrorActionPreference, содержащим 'Continue', возможно, только в локальной области видимости) завершающая ошибка выражения / другой команды фактически становится не определяющей ошибку с точки зрения вызывающей стороны.

      • Если для $ErrorActionPreference установлено значение 'Stop', исходная ошибка завершения оператора преобразуется в ошибку, * script .

1 голос
/ 25 апреля 2019

Похоже, что вы можете сделать это с явной настройкой параметров по умолчанию в $PSDefaultParameterValues общесессионной переменной предпочтения .

Это включает в себя возможность установки ErrorAction Общий параметр по умолчанию для определенных функций.Имейте в виду, что вы бы хотели добавить текущее значение $PSDefaultParameterValues, так как оно использует хеш-таблицу, и другие функции в настоящее время могут иметь значения по умолчанию, установленные в текущем сеансе.Это также означало бы, что [CmdletBinding()] необходимо включить в каждую функцию, для которой задано это значение по умолчанию.

$PSDefaultParameterValues - это хеш-таблица , поэтомувам нужно изменить таким образом:

$PSDefaultParameterValues += @{
    "Get-Function:ErrorAction"="Stop"
    "Get-Command:ErrorAction"="Stop"
    "Get-MyFunction*:ErrorAction"="Stop"
}

или

$PSDefaultParameterValues.add("Get-Function:ErrorAction","Stop")

Подстановочные знаки принимаются в именах функций / командлетов, что может упростить егочтобы получить все ваши функции в одной строке, если у вас есть уникальная схема именования префиксов существительных для импорта из вашего модуля (хотя это будет включать любые другие функции / командлеты, если они будут импортированы в сеанс с тем же префиксом именования).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...