Heb je ooit een script of een PowerShell-cmdlet uitgevoerd en werd je geconfronteerd met een schreeuwend muur van tekst – in het rood – zoals hieronder getoond?

Fouten kunnen overweldigend en verwarrend worden. En vooral, fouten zijn vaak moeilijk te lezen, waardoor het bijna onmogelijk is om te bepalen wat en waar het script fout is gegaan.
Gelukkig heb je enkele opties in PowerShell om dit beter te maken via foutafhandeling. Met foutafhandeling kunnen fouten worden gefilterd en weergegeven op een manier die het gemakkelijker maakt om er zin van te maken. En, het begrijpen van de fout maakt het gemakkelijk om meer logica toe te voegen aan foutafhandeling.
In dit artikel leer je over fouten in PowerShell en hoe ze kunnen worden onderschept om foutafhandeling uit te voeren met behulp van de PowerShell Try Catch
-blokken (en finally
-blokken).
Begrijpen hoe fouten werken in PowerShell
Voordat we ingaan op foutafhandeling, laten we eerst een paar concepten rond fouten in PowerShell behandelen. Het begrijpen van fouten kan leiden tot betere strategieën voor foutafhandeling.
De $Error
Automatische Variabele
In PowerShell zijn er veel automatische variabelen, en een daarvan is de $Error
automatische variabele. PowerShell gebruikt de $Error
variabele om alle fouten op te slaan die in de sessie worden aangetroffen. De $Error
variabele is een array van fouten gesorteerd op meest recente.
Wanneer je voor het eerst een PowerShell-sessie opent, is de variabele $Error
leeg. Je kunt dit controleren door de variabele $Error
aan te roepen.

Zoals je kunt zien, begint de variabele $Error
leeg. Maar, zodra er een fout optreedt, wordt de fout toegevoegd en opgeslagen in de variabele $Error
.
In het onderstaande voorbeeld wordt de fout gegenereerd door bewust een servicenaam op te vragen die niet bestaat.

Zoals je kunt zien aan de bovenstaande output, werd de gegenereerde fout toegevoegd aan de variabele $Error
.
De variabele $Error bevat een verzameling fouten die zijn gegenereerd in de PowerShell-sessie. Elke fout kan worden opgevraagd door de arraypositie aan te roepen. De meest recente fout staat altijd op index 0.
Bijvoorbeeld, de meest recente fout kan worden opgehaald met
$Error[0]
.
De eigenschappen van het object $Error
Aangezien alles in PowerShell een object is, is de variabele $Error
een object, en objecten hebben eigenschappen. Door de variabele $Error
door te sturen naar de cmdlet Get-Member
, zou je de lijst met beschikbare eigenschappen moeten zien.

Om de reden voor de fout te bepalen, kun je de inhoud van de eigenschap InvocationInfo
bekijken met het onderstaande commando.

Nu zou je hetzelfde kunnen doen met de andere eigenschappen en ontdekken welke andere informatie je kunt vinden!
Terminale Fouten
Beëindigingsfouten stoppen de uitvoeringsstroom wanneer deze wordt tegengekomen door PowerShell, in tegenstelling tot niet-beëindigingsfouten. Er zijn verschillende manieren waarop een beëindigingsfout kan optreden. Een voorbeeld is wanneer u een cmdlet aanroept met een parameter die niet bestaat.
Zoals u kunt zien aan de onderstaande schermafbeelding, wanneer het commando Get-Process notepad
wordt uitgevoerd, is het commando geldig en worden de details van het notepad-proces weergegeven.

Maar wanneer een parameter die niet bestaat wordt gebruikt, zoals Get-Process notepad -handle 251
, geeft de cmdlet een foutmelding dat de handle
-parameter niet geldig is. Vervolgens wordt de cmdlet afgesloten zonder de details van het notepad
-proces weer te geven.

Niet-Beëindigingsfouten
Niet-beëindigingsfouten zijn fouten die de uitvoering van het script of commando niet stoppen. Bekijk bijvoorbeeld de onderstaande code. Deze code haalt de lijst met bestandsnamen op uit het bestandslijst.txt-bestand. Vervolgens doorloopt het script elke bestandsnaam, leest de inhoud van elk bestand en geeft deze weer op het scherm.
De inhoud van het bestandslijst.txt-bestand zijn de bestandsnamen die in de onderstaande lijst worden weergegeven.
Maar wat als File_6.log eigenlijk niet bestond? Wanneer u de code uitvoert, zou u verwachten dat er een fout optreedt omdat het script het File_6.log niet kan vinden. U ziet een soortgelijke uitvoer zoals hieronder getoond.

Zoals je kunt zien aan de screenshot van het bovenstaande resultaat, kon het script de eerste vijf bestanden in de lijst lezen, maar toen het probeerde het bestand File_6.txt, te lezen, trad er een fout op. Het script ging vervolgens door met het lezen van de rest van de bestanden voordat het werd afgesloten. Het heeft niet geëindigd.
De variabele $ErrorActionPreference
Je hebt tot nu toe geleerd over de afsluitende en niet-afsluitende fouten en hoe ze van elkaar verschillen. Maar wist je dat een niet-afsluitende fout kan worden gedwongen om als een afsluitende fout te worden behandeld?
PowerShell heeft een concept genaamd preferentievariabelen. Deze variabelen worden gebruikt om de manier waarop PowerShell op veel verschillende manieren werkt, te wijzigen. Een van deze variabelen is genaamd $ErrorActionPreference
.
De variabele $ErrorActionPreference
wordt gebruikt om de manier waarop PowerShell niet-afsluitende fouten behandelt, te wijzigen. Standaard is de waarde van $ErrorActionPreference
ingesteld op Continue
. Door de waarde van de variabele $ErrorActionPreference
te wijzigen naar STOP
, dwingt PowerShell af dat alle fouten als afsluitende fouten worden behandeld.
Gebruik de onderstaande code om de waarde van $ErrorActionPreference
te wijzigen.
Om meer te weten te komen over andere geldige waarden van de variabele $ErrorActionPreference, bezoek PowerShell ErrorActionPreference.
Verwijs nu terug naar het voorbeeld gebruikt in het Non-Terminating Errors gedeelte in dit artikel. Het script kan worden aangepast om de wijziging in $ErrorActionPreference
op te nemen zoals weergegeven in de onderstaande code:
Het uitvoeren van de aangepaste code hierboven zal zich anders gedragen dan voorheen wanneer de waarde van $ErrorActionPreference
is ingesteld op de standaardwaarde van Continue
.

$ErrorActionPreference
variableZoals te zien is op de screenshot van het resultaat hierboven, kon het script de eerste vijf bestanden in de lijst lezen, maar toen het probeerde het bestand File_6.txt te lezen, trad er een fout op omdat het bestand niet werd gevonden. Vervolgens werd het script beëindigd en werden de overige bestanden niet gelezen.
De waarde van
$ErrorActionPreference
is alleen geldig in de huidige PowerShell-sessie. Het wordt gereset naar de standaardwaarde zodra een nieuwe PowerShell-sessie wordt gestart.
De Common Parameter ErrorAction
Als de waarde van `$ErrorActionPreference` wordt toegepast op de PowerShell-sessie, is de parameter `ErrorAction` van toepassing op elke cmdlet die algemene parameters ondersteunt. De parameter `ErrorAction` accepteert dezelfde waarden als de variabele `$ErrorActionPreference` doet.
De waarde van de parameter `ErrorAction` heeft voorrang op de waarde van `ErrorActionPreference`.
Laten we teruggaan en dezelfde code gebruiken als in het vorige voorbeeld. Maar deze keer wordt de parameter `ErrorAction` toegevoegd aan de regel `Get-Content`.
Na het uitvoeren van de aangepaste code, zul je zien dat zelfs als `$ErrorActionPreference` is ingesteld op `Continue`, het script nog steeds wordt beëindigd zodra het een fout tegenkomt. Het script wordt beëindigd omdat de PowerShell `ErrorAction` parameterwaarde in `Get-Content` is ingesteld op `STOP`.

ErrorAction
parameterGebruik van PowerShell Try Catch Blocks
Op dit punt heb je geleerd over PowerShell-fouten en hoe de variabele `$ErrorActionPreference` en de PowerShell `ErrorAction` parameters werken. Nu is het tijd dat je leert over de goede dingen – de PowerShell `Try Catch Finally` blokken.
$equation$PowerShell \texttt{try catch}$$ blocks (and optional \texttt{finally block}) are een manier om een net om een stuk code te werpen en eventuele fouten die optreden te vangen.
De onderstaande code toont de syntaxis van de \texttt{Try}-verklaring.
De \texttt{Try}-blok bevat de code die je wilt dat PowerShell “probeert” te monitoren op fouten. Als de code in het \texttt{Try}-blok een fout tegenkomt, wordt de fout toegevoegd aan de \texttt{\$Error}-variabele en vervolgens doorgegeven aan het \texttt{Catch}-blok.
Het \texttt{Catch}-blok bevat de acties die moeten worden uitgevoerd wanneer het een fout van het \texttt{Try}-blok ontvangt. Er kunnen meerdere \texttt{Catch}-blokken zijn in een \texttt{Try}-verklaring.
Het \texttt{Finally}-blok bevat de code die aan het einde van de \texttt{Try}-verklaring wordt uitgevoerd. Dit blok wordt uitgevoerd, ongeacht of er een fout is opgetreden.
Het vangen van niet-specifieke fouten (Catch-All) met PowerShell ErrorAction
A simple Try
statement contains a Try
and a Catch
block. The Finally
block is optional.
Bijvoorbeeld, om een niet-specifieke uitzondering op te vangen, moet de \texttt{Catch}-parameter leeg zijn. De onderstaande voorbeeldcode maakt gebruik van hetzelfde script dat werd gebruikt in de sectie De \$ErrorActionPreference-variabele, maar is aangepast om de \texttt{Try Catch}-blokken te gebruiken.
Zoals je kunt zien aan de hand van de onderstaande code, is dit keer de \texttt{foreach}-verklaring ingesloten in het \texttt{Try}-blok. Vervolgens bevat een \texttt{Catch}-blok de code om de tekst \texttt{Er is een fout opgetreden} weer te geven als er een fout is opgetreden. De code in het \texttt{Finally}-blok wist gewoon de \texttt{\$Error}-variabele.
De bovenstaande code, nadat het in PowerShell is uitgevoerd, geeft het volgende resultaat.

Het bovenstaande resultaat toont aan dat het script een fout heeft ondervonden, de code binnen het Catch
-blok heeft uitgevoerd, en vervolgens is gestopt.
De fout is afgehandeld, wat het doel was van foutafhandeling. Echter, de weergegeven fout was te algemeen. Om een meer beschrijvende fout weer te geven, kunt u toegang krijgen tot de Exception
-eigenschap van de fout die is doorgegeven door het Try
-blok.
De onderstaande code is aangepast, specifiek de code binnen het Catch
-blok, om het uitzonderingsbericht van de huidige fout weer te geven die is doorgegeven via de pijplijn – $PSItem.Exception.Message
Deze keer, wanneer de gewijzigde code hierboven wordt uitgevoerd, wordt het weergegeven bericht veel meer beschrijvend.

Specifieke Fouten Afhandelen
Er zijn momenten waarop een ‘vang alles’ foutafhandeling niet de meest geschikte aanpak is. Misschien wilt u dat uw script een actie uitvoert die afhankelijk is van het type fout dat wordt aangetroffen.
Hoe bepaalt u het fouttype? Door de TypeName
-waarde van de Exception
-eigenschap van de laatste fout te controleren. Om bijvoorbeeld het fouttype uit het vorige voorbeeld te vinden, gebruikt u deze opdracht:
Het resultaat van de bovenstaande code zou eruitzien als de onderstaande screenshot. Zoals u kunt zien, wordt de TypeName
-waarde weergegeven – System.Management.Automation.ItemNotFoundException
.

Nu je het fouttype kent dat je moet onderscheppen, wijzig je de code om het specifiek te vangen. Zoals je kunt zien in de aangepaste code hieronder, zijn er nu twee `Catch`-blokken. Het eerste `Catch`-blok onderschept een specifiek type fout (`System.Management.Automation.ItemNotFoundException`). Daarentegen bevat het tweede `Catch`-blok het generieke, vang-alles foutbericht.
De onderstaande schermafbeelding toont de uitvoer van de hierboven aangepaste code.

Conclusie
In dit artikel heb je geleerd over fouten in PowerShell, de eigenschappen ervan, en hoe je het specifieke type fout kunt bepalen. Je hebt ook het verschil geleerd tussen hoe de variabele `$ErrorActionPreference` en de PowerShell `ErrorAction`-parameter bepalen hoe PowerShell niet-terminale fouten behandelt.
Je hebt ook geleerd hoe je de PowerShell `Try Catch Finally`-blokken kunt gebruiken voor foutafhandeling, zowel voor specifieke fouten als voor een vang-alles benadering.
De voorbeelden die in dit artikel worden getoond, demonstreren alleen de basisprincipes van hoe de `Try Catch Finally`-blokken werken. De kennis die ik hoop dat je hebt opgedaan in dit artikel zou je de startblokken moeten geven om foutafhandeling toe te passen in je scripts.