Powershell: Wie kann ich verhindern, dass Fehler in einem Skript angezeigt werden?

90

Wenn mein PowerShell-Skript beispielsweise versucht, ein SQL Server-Objekt für einen nicht vorhandenen Server zu erstellen (in meinem Fall "bla"), zeigt PowerShell viele PowerShell-Fehler in Rot an.

Da mein Skript den Wert von $?nach solchen Aufrufen überprüft und Fehler anzeigt und protokolliert, möchte ich lieber nicht, dass auch die verschiedenen Zeilen mit PowerShell-Fehlern angezeigt werden.

Wie kann ich diejenigen deaktivieren, die für mein Skript angezeigt werden?

Andrew J. Brehm
quelle

Antworten:

130

Sie haben mehrere Möglichkeiten. Am einfachsten ist es, die ErrorActionEinstellungen zu verwenden.

-Erroractionist ein universeller Parameter für alle Cmdlets. Wenn Sie spezielle Befehle ignorieren möchten, können Sie diese verwenden, -erroraction 'silentlycontinue'wodurch grundsätzlich alle von diesem Befehl generierten Fehlermeldungen ignoriert werden. Sie können auch den IgnoreWert verwenden (in PowerShell 3+):

Im Gegensatz zu SilentlyContinue fügt Ignore die Fehlermeldung nicht zur automatischen Variablen $ Error hinzu.

Wenn Sie alle Fehler in einem Skript ignorieren möchten, können Sie die Systemvariable verwenden $ErrorActionPreferenceund dasselbe tun:$ErrorActionPreference= 'silentlycontinue'

Siehe about_CommonParameters für weitere Informationen über -ErrorAction. Siehe about_Preference_Variables für weitere Informationen über $ ErrorActionPreference.

JNK
quelle
Benötigen Sie ein einfaches Anführungszeichen in -erroraction 'Silentcontinue'? Intellisese zeigt Optionen an und fügt kein einfaches Anführungszeichen hinzu.
PAS
Wenn das obige Format für Sie nicht funktioniert, verweisen Sie auf den oben angegebenen Link. Ich musste wie -ErrorAction:SilentlyContinuein PS 5.1 formatieren . Ich habe mein Cmdlet aus dem Stapel aufgerufen, daher weiß ich nicht, ob dies einen Unterschied macht. Aber gute Informationen, wenn Sie wissen, dass ein akzeptabler Fehler vorliegt, können ausgelöst werden.
David
--rm. \ Windows.old \ -Force -Recurse -Verbose -ErrorAction SilentlyContinue -WarningAction SilentlyContinue </ code>
Tertius Geldenhuys
17

Windows PowerShell bietet zwei Mechanismen zum Melden von Fehlern: einen Mechanismus zum Beenden von Fehlern und einen anderen Mechanismus zum Nichtbeenden von Fehlern .

Interner CmdLets-Code kann eine ThrowTerminatingErrorMethode aufrufen , wenn ein Fehler auftritt, der es dem Cmdlet nicht erlaubt oder nicht erlauben sollte, seine Eingabeobjekte weiter zu verarbeiten. Der Skriptschreiber kann diese Ausnahme verwenden, um diesen Fehler abzufangen.

EX :

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

Interner CmdLets-Code kann eine WriteErrorMethode aufrufen , um nicht terminierende Fehler zu melden, wenn das Cmdlet die Eingabeobjekte weiter verarbeiten kann. Der Skriptschreiber kann dann die Option -ErrorAction verwenden, um die Nachrichten auszublenden, oder die Option verwenden, um $ErrorActionPreferencedas gesamte Skriptverhalten einzurichten .

JPBlanc
quelle
7

Ich hatte ein ähnliches Problem beim Versuch, Hostnamen mit aufzulösen [system.net.dns]. Wenn die IP nicht aufgelöst wurde. Net hat einen Beendigungsfehler ausgegeben. Um den Beendigungsfehler zu vermeiden und dennoch die Kontrolle über die Ausgabe zu behalten, habe ich eine Funktion mit erstellt TRAP.

Z.B

Function Get-IP 
{PARAM   ([string]$HostName="")
PROCESS {TRAP 
             {"" ;continue} 
             [system.net.dns]::gethostaddresses($HostName)
        }
}
DW
quelle
4

Du bist hier weit weg von der Spur.

Sie haben bereits eine schöne, große Fehlermeldung. Warum um alles in der Welt möchten Sie Code schreiben, der $?nach jedem einzelnen Befehl explizit überprüft wird ? Dies ist enorm umständlich und fehleranfällig. Die richtige Lösung ist , die Überprüfung zu beenden$? .

Verwenden Sie stattdessen den in PowerShell integrierten Mechanismus, um für Sie in die Luft zu jagen. Sie aktivieren es, indem Sie die Fehlereinstellung auf die höchste Stufe setzen:

$ErrorActionPreference = 'Stop'

Ich setze dies an die Spitze jedes einzelnen Skripts, das ich jemals geschrieben habe, und jetzt muss ich es nicht mehr überprüfen $?. Dies macht meinen Code wesentlich einfacher und zuverlässiger.

Wenn Sie auf Situationen stoßen, in denen Sie dieses Verhalten wirklich deaktivieren müssen, können Sie entweder catchden Fehler beheben oder eine Einstellung mithilfe der allgemeinen Funktion an eine bestimmte Funktion übergeben -ErrorAction. In Ihrem Fall möchten Sie wahrscheinlich, dass Ihr Prozess beim ersten Fehler stoppt, den Fehler abfängt und dann protokolliert.

Beachten Sie, dass dies nicht der Fall ist, wenn externe ausführbare Dateien fehlschlagen (Exit-Code ungleich Null, konventionell). Sie müssen also immer noch prüfen, $LASTEXITCODEob Sie welche aufrufen. Trotz dieser Einschränkung spart die Einstellung immer noch viel Code und Aufwand.

Zusätzliche Zuverlässigkeit

Möglicherweise möchten Sie auch den strengen Modus verwenden :

Set-StrictMode -Version Latest

Dies verhindert, dass PowerShell stillschweigend fortgesetzt wird, wenn Sie eine nicht vorhandene Variable verwenden und in anderen seltsamen Situationen. ( -VersionEinzelheiten zu den Einschränkungen finden Sie im Parameter.)

Durch die Kombination dieser beiden Einstellungen wird PowerShell wesentlich fehlerfreier, was die Programmierung erheblich vereinfacht.

jpmc26
quelle
2

Fügen Sie -ErrorAction SilentlyContinueIhrem Skript hinzu, und Sie können loslegen.

Jayant Rajwani
quelle
2

In einigen Fällen können Sie nach dem Befehl eine Out-Null weiterleiten

command | Out-Null
Beere
quelle
-1

Wenn Sie möchten, dass die Powershell-Fehlermeldung für ein Cmdlet unterdrückt wird, der Fehler jedoch weiterhin abgefangen werden soll, verwenden Sie "-erroraction 'silentlyStop'".

Mikkel Vejlby
quelle
Es gibt keine solche Aktion. Obwohl es eine Stop-Aktion gibt.
Marvin Dickhaus
Aber es erlaubt, rote Fehlermeldung zu unterdrücken und weiterhin catch Befehl / Abschnitt zu verwenden, wenn New-Item -ItemType directory(PowerShell v2.0)
Milan Kerslager
@MilanKerslager Könnten Sie bitte ein Codebeispiel zeigen - da ich und alle anderen glauben, dass es keine ActionPreference wie '
SilentlyStop
Ich bin mir ziemlich sicher, dass Mikkel SilentlyContinue und nicht SilentStop gemeint hat, da dies inhaltlich viel sinnvoller ist.
John