Die ganze Idee einer try/catch Steuerung ist, dass Sie das Skript sagen, was es tun, wenn ein Abschluss Fehler auftritt, statt der Standardaktion der Fehler zu werfen und Stoppen der Skript. Wenn Ihr catch-Block nur eine Nachricht an das Terminal mit Write-Host anzeigt, ist das die einzige Fehlerbehandlung, die es gibt, und das Skript wird von dort fortgesetzt. Wenn Sie darüber nachdenken, würde es teilweise den Zweck von versuchen/fangen besiegen, wenn das Skript automatisch gestoppt wurde, wenn ein Fehler auftritt.
Im catch Block, _ $ wird den Abschluss Fehler an das Errorrecord Objekt festgelegt wird, darstellt, von den Block (das gleiches, die in $ Fehlern gespeichert werden [0]) versuchen.So ist der einfachste Weg, um das Skript zu beenden, ist der Fehler erneut auslösen, die ausgelöst worden wäre, wenn Sie nicht benutzt hatten ein try/catch:
try {
Get-Content "c:\GarbageFileName.txt" -ErrorAction stop
} catch {
# Custom action to perform before terminating
throw $_
}
Oder, wenn Sie eine benutzerdefinierte Meldung angezeigt werden sollen statt die Standarderrorrecord:
try {
Get-Content "c:\GarbageFileName.txt" -ErrorAction stop
} catch {
throw 'Custom error message'
}
Oder Sie Pause in Joost Antwort wie vorgeschlagen verwenden können, wenn Sie wollen einfach nur beenden, nachdem Sie mit Ihrem eigenen Fehlerbehandlung fertig sind, ohne einen Fehler an den Fehlerstrom zu werfen.
Oder Sie könnten anspruchsvoller und erstellen Sie Ihr eigenes ErrorRecord-Objekt. Es gibt eine Menge, die Sie damit tun können, es ist ein zu großes Thema, das hier umfassend behandelt werden kann, aber Sie können weitere Informationen über die Syntax erhalten, indem Sie googlen System.Management.Automation.ErrorRecord. Hier ist ein Beispiel von einem meines Skripte zu Ihnen (aus einer Funktion, die eine SQL-Abfrage ausführt, in dem definierten $ query Variable für eine SQL Server-Datenbank) loszuzulegen:
} catch {
$ErrorRecord = New-Object System.Management.Automation.ErrorRecord(
(New-Object Exception("Exception executing the query: $($_.Exception.InnerException.Message)")),
$query,
[System.Management.Automation.ErrorCategory]::InvalidArgument,
$null
)
$ErrorRecord.CategoryInfo.Reason = $_.CategoryInfo.Reason;
$ErrorRecord.CategoryInfo.Activity = $_.InvocationInfo.InvocationName;
$PSCmdlet.ThrowTerminatingError($ErrorRecord);
}
Ein paar Anmerkungen:
- Sie werden sehen, dass meine benutzerdefinierte Errorrecord schaffen, ich bin mit $ _, die ich das Objekt Errorrecord gerade gesagt enthält der Abschluss Fehler zugeordnet, die in der Block versuchen gefangen wurde. Die Idee besteht darin, einen Teil der Fehlerausgabe anzupassen, während Teile des Standard-ErrorRecord verwendet werden, indem sie den entsprechenden Eigenschaften für das benutzerdefinierte ErrorRecord zugewiesen werden.
- $ PSCmdlet ist nur verfügbar, wenn Sie am Anfang der Funktion oder des Skripts
[CmdletBinding()]
deklarieren. Andernfalls können Sie einfach throw $ErrorRecord
verwenden, um Ihren benutzerdefinierten Fehler zu werfen. Das Ergebnis wird jedoch mehr Cmdletstil sein, wenn Sie $ PSCmdlet.ThrowTerminatingError verwenden. (throw spuckt die Linie von der Funktion zurück, die den Fehler erzeugte, während $ PSCmdlet.ThrowTerminatingError Ihnen die Linie vom aufrufenden Kontext gibt, in dem die Funktion verwendet wurde. Es ist schwer, in einer Weise zu beschreiben, die ohne Sinn sinnvoll ist zu aufwendig bekommen, aber wenn Sie mit ihm experimentieren werden Sie sehen, was ich meine.)
BTW, ist es überflüssig $ErrorActionPreference = "Stop"
, zu setzen und dann -ErrorAction Stop
verwenden. Die Einstellungsvariable setzt die Standardaktion für alle Cmdlets, und der Schalter -ErrorAction überschreibt die Standardaktion für ein bestimmtes Cmdlet. Sie müssen also nicht zuerst den Standardwert angeben und dann -ErrorAction verwenden, um dieselbe Aktion anzugeben, die Sie gerade ausführen Als Standard festlegen. Was Sie wahrscheinlich tun möchten, ist $ErrorActionPreference = "Stop"
weglassen.
werfen Sie die Ausnahme, die Sie fangen? Ich weiß Powershell nicht, aber das ist, was Sie in Java tun würden. –
In diesem Fall, warum nicht einfach ein 'Test-Path $ TargetFile' und dann' Get-Content' verwenden, wenn es erfolgreich ist? – Eris