Powershell: как отключить отображение ошибок в скрипте?

94

Когда мой сценарий PowerShell пытается, например, создать объект SQL Server для несуществующего сервера (в моем случае «bla»), PowerShell отображает множество ошибок PowerShell красным цветом.

Поскольку мой сценарий проверяет значение $?после таких вызовов, а также отображает и регистрирует ошибки, я бы предпочел не отображать несколько строк с ошибками PowerShell.

Как я могу отключить те, которые отображаются для моего скрипта?

Эндрю Дж. Брем
источник

Ответы:

140

У вас есть несколько вариантов. Самый простой - использовать ErrorActionнастройки.

-Erroraction- универсальный параметр для всех командлетов. Если есть специальные команды, которые вы хотите игнорировать, вы можете использовать, -erroraction 'silentlycontinue'которые в основном игнорируют все сообщения об ошибках, генерируемые этой командой. Вы также можете использовать Ignoreзначение (в PowerShell 3+):

В отличие от SilentlyContinue, Ignore не добавляет сообщение об ошибке в автоматическую переменную $ Error.

Если вы хотите игнорировать все ошибки в скрипте, вы можете использовать системную переменную $ErrorActionPreferenceи сделать то же самое:$ErrorActionPreference= 'silentlycontinue'

См. About_CommonParameters для получения дополнительной информации о -ErrorAction. См. About_preference_variables для получения дополнительной информации о $ ErrorActionPreference.

JNK
источник
вам нужна одинарная кавычка в -erroraction 'silently continue'? Intellisese показывает параметры, а не добавляет одинарную кавычку.
PAS
1
Если указанный выше формат вам не подходит, обратитесь по приведенной выше ссылке. Пришлось форматировать как -ErrorAction:SilentlyContinueв PS 5.1. Я вызывал свой командлет из пакета, поэтому не знаю, имеет ли это значение. Но хорошая информация, когда вы знаете, что допустимая ошибка может быть выброшена.
Дэвид
--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </code>
Tertius Geldenhuys
18

Windows PowerShell предоставляет два механизма для сообщения об ошибках: один механизм для прерывания ошибок и другой механизм для непрерывных ошибок .

Внутренний код CmdLets может вызывать ThrowTerminatingErrorметод при возникновении ошибки, которая не позволяет или не должна позволять командлету продолжать обработку своих входных объектов. Автор сценария может использовать исключение, чтобы отловить эту ошибку.

EX:

try
{
  Your database code
}
catch
{
  Error reporting/logging
}

Внутренний код CmdLets может вызывать WriteErrorметод для сообщения о непрекращающихся ошибках, когда командлет может продолжить обработку входных объектов. Затем автор сценария может использовать параметр -ErrorAction, чтобы скрыть сообщения, или использовать $ErrorActionPreferenceдля настройки всего поведения сценария.

JPBlanc
источник
8

У меня была аналогичная проблема при попытке разрешить имена хостов с помощью [system.net.dns]. Если IP не был разрешен .Net выдает завершающую ошибку. Чтобы предотвратить завершающую ошибку и при этом сохранить контроль над выводом, я создал функцию, используя TRAP.

НАПРИМЕР

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}
DW
источник
3

Вы здесь сбились с пути.

У вас уже есть большое сообщение об ошибке. Зачем вам писать код, который $?явно проверяет каждую команду ? Это чрезвычайно громоздко и подвержено ошибкам. Правильное решение - прекратить проверку$? .

Вместо этого используйте встроенный механизм PowerShell, чтобы взорвать вас. Вы включаете его, установив предпочтение ошибок на самый высокий уровень:

$ErrorActionPreference = 'Stop'

Я помещаю это в начало каждого сценария, который когда-либо писал, и теперь мне не нужно проверять $?. Это делает мой код намного проще и надежнее.

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

Обратите внимание, что это не относится к случаю, когда внешние исполняемые файлы терпят неудачу (обычно код выхода ненулевой), поэтому вам все равно нужно проверить $LASTEXITCODE, вызываете ли вы какой-либо. Несмотря на это ограничение, настройка по-прежнему позволяет сэкономить много кода и усилий.

Дополнительная надежность

Вы также можете рассмотреть возможность использования строгого режима :

Set-StrictMode -Version Latest

Это препятствует тому, чтобы PowerShell молча продолжал работу, когда вы используете несуществующую переменную и в других странных ситуациях. ( -VersionПодробнее о том, что он ограничивает, см. В параметре.)

Сочетание этих двух настроек делает PowerShell гораздо более отказоустойчивым языком, что значительно упрощает программирование на нем.

jpmc26
источник
2

Добавьте -ErrorAction SilentlyContinueв свой сценарий, и все будет хорошо.

Джаянт Раджвани
источник
2

В некоторых случаях вы можете передать после команды Out-Null

command | Out-Null
Ягода
источник
-1

Если вы хотите, чтобы сообщение об ошибке PowerShell для командлета было подавлено, но все же хотите перехватить ошибку, используйте «-erroraction 'silentlyStop'»

Миккель Вейлби
источник
Нет такого действия. Хотя есть действие Stop.
Марвин Дикхаус,
Но это позволяет подавить красное сообщение об ошибке и по-прежнему использовать команду / раздел catch при использовании New-Item -ItemType directory(PowerShell v2.0)
Милан Керслагер
@MilanKerslager, не могли бы вы показать образец кода - поскольку я и все остальные считаю, что не существует такого ActionPreference, как 'SilentlyStop'
FSCKur
Я достаточно уверен, что Миккель имел в виду SilentlyContinue, а не silentlyStop, потому что это имеет больше смысла в содержании того, что вы хотите, чтобы он делал.
Джон