Zoals de naam al aangeeft, is PowerShell veel krachtiger dan de standaard Windows opdrachtprompt. Met die kracht komt een grotere kans op verwarrende fouten. Als uw script plotseling mislukt, weet u misschien niet waar u moet beginnen met zoeken naar wat er mis is gegaan. Dit is waar PowerShell’s foutafhandeling van pas komt.
Als u bekend bent met andere talen, kent u waarschijnlijk de basisprincipes van foutafhandeling, maar er zijn enkele aspecten die specifiek zijn voor PowerShell die u moet kennen. Er zijn vier onderdelen voor foutafhandeling in PowerShell: de Error Action parameter, Try/Catch blokken, de Error Variable parameter, en logging.
PowerShell Error Handling the Easy Way
De eerste stap in het omgaan met PowerShell fouten is het omgaan met iets dat je script stopt in zijn tracks. Als de fout geen invloed heeft op de rest van uw script, kan het het beste zijn om PowerShell te vertellen om fouten te negeren en verder te gaan.
Aan de andere kant is het niet altijd duidelijk wanneer een bepaald cmdlet een terminating error geeft. Sommige cmdlets geven een foutmelding, maar stoppen uw script niet. Dit kan ertoe leiden dat u moet wachten tot uw script is voltooid terwijl het onzin uitvoert.
Dit is waar de -ErrorAction parameter om de hoek komt kijken. Je gebruikt deze om een cmdlet te dwingen de fout af te handelen op de manier die jij wilt. Als je een bestaand script wijzigt, voeg je het toe aan het eind van de cmdlet regel.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop
Het is duidelijk dat als je het Get-ChildItem cmdlet op zichzelf gebruikt, deze foutmelding niet veel voor je doet. Als u echter iets met de gegevens wilt doen, zou het goed zijn om het script te stoppen, zodat u weet dat de zoekopdracht is mislukt en waarom. Als alternatief, als u meerdere zoekacties uitvoert, verander de parameter van Stop in SilentlyContinue, zodat het script doorgaat als een zoekactie mislukt. Als u wilt zien wat de fout is, kunt u in plaats daarvan Doorgaan als parameter gebruiken.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction SilentlyContinue
Als je liever de optie hebt om te bepalen wat er gebeurt elke keer dat je script wordt uitgevoerd, kun je het veranderen in Inquire. Wanneer je cmdlet op een probleem stuit, geeft het opties: Yes, Yes For All, Halt Command, Suspend, of Help.
Deze optie is wat flexibeler, maar betekent wel dat uw script bij fouten op uw invoer moet wachten. Dat is prima als u PowerShell gebruikt om een e-mail of een andere eenvoudige taak te verzenden, maar het is misschien niet iets wat u wilt als u ’s nachts een lang proces uitvoert.
PowerShell Error Handling the Powerful Way
De parameter ErrorAction pakt uw fouten op een ongecompliceerde manier aan. Echter, als u op zoek bent naar een beetje meer controle over fouten, PowerShell heeft u nog steeds gedekt. Met behulp van Try/Catch kunnen we nu het script vertakken wanneer cmdlets een fout retourneren.
Zoals de naam al doet vermoeden, bestaat Try/Catch uit twee delen. (Er is technisch gezien nog een derde, maar daar komen we zo op.) Het eerste deel is het gedeelte Try. U gaat uw normale code in deze sectie uitvoeren. Je gaat nog steeds de -ErrorAction parameter gebruiken, maar die kan alleen ingesteld worden als Stop. Deze flag zorgt ervoor dat je cmdlet de Catch activeert–zelfs als het geen afsluitende fout heeft.
Try{
Get-Process "Cortana" -ErrorAction Stop
}
Try kan ook voorkomen dat andere cmdlets worden uitgevoerd als de zoekopdracht mislukt. In dit geval, als je de Get-Process resultaten naar Stop-Process stuurt, voorkomt een mislukte zoekopdracht dat het tweede cmdlet wordt uitgevoerd.
Dus nu dat je een try block van cmdlets hebt gemaakt, wat wil je doen als het mislukt? Met behulp van de Catch helft, ga je dit definiëren.
Catch{
Write-Host "Process Not Found"
}
Net als bij de parameter ErrorAction zal Catch, wanneer je iets wat ingewikkelder doet, voor meer nuttig zijn dan het geven van een gewone taalfout. (In het bovenstaande voorbeeld wordt de fout geforceerd door de app naam te gebruiken, en niet de proces naam). Zorg er dus voor dat je speelt met het Try blok om een zoekopdracht/actie te maken die je nodig hebt. Je kunt het Catch blok gebruiken om je script een email te laten sturen als het mislukt.
Het derde deel komt van pas als je iets wilt laten lopen ongeacht of je cmdlet slaagt of niet. Hiervoor kun je het Finally blok gebruiken. Je voegt dit toe na Try en Catch en logt wanneer een deel van je script eindigt.
De Error Variable en Logging
Je script regelt nu hoe het fouten afhandelt en hoe het daarop reageert. U kunt het als een geplande taak gebruiken, of het in ieder geval uitvoeren als u niet achter uw bureau zit. Maar hoe kan je een mislukt script onderzoeken? Met de parameter -ErrorVariable schrijf je de fouten van je cmdlet naar een aangepaste variabele.
Dit is een alternatief voor de systeemvariabele $Error, die alle fouten van de huidige sessie bevat.
Je cmdlet moet een beetje langer worden. Definieer eerst een variabele, iets als $SearchError zal volstaan voor het voorbeeld. Wanneer je SearchError aanroept in de ErrorVariable parmeter, gebruik je het dollarteken niet.
Ook al roep je een variabele aan die je zelf hebt gemaakt, door de manier waarop de parameter werkt roep je hem aan zonder het dollarteken. Voeg dat dan toe aan het eind van de regel.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Continue -ErrorVariable SearchError
Als je een + voor de naam van de variabele zet, kun je de variabele aanvullen in plaats van vervangen. Dat geeft je hetzelfde gedrag als de globale fout variabele. In plaats daarvan kun je deze uitvoer en Try/Catch gebruiken om aangepaste uitvoer te schrijven, en die een tijdstempel geven.
Om dit te laten werken, moet u een tekstbestand maken direct nadat u de foutvariabele hebt ingesteld. Doe dit met het cmdlet New-Item. Misschien wil je de Inquire optie gebruiken voor de ErrorAction parameter. Hiermee kun je aan een bestaand logboek toevoegen wanneer het New-Item cmdlet mislukt.
$SearchLog = New-Item "~\SearchLog.txt" -type file -ErrorAction Inquire
Wanneer je nu je Try/Catch blok bouwt, kun je de Catch gebruiken om te loggen naar een tekst bestand. Je gebruikt Get-Date om de tijdstempel te maken. De formattering kan lastig zijn, dus zorg ervoor dat je die uit het voorbeeld overneemt.
Try{
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop -ErrorVariable SearchError
}
Catch{
Add-Content -Path $SearchLog -Value "$(Get-Date -Format dd-MM-yy-hh_mm_ss) Files not found returned error: $SearchError"
}
Herhaal dat zo nodig voor al je cmdlets, en je hebt nu een mooi log van eventuele fouten. Als je dingen wilt bijhouden die met succes worden uitgevoerd, kun je een soortgelijke Add-Content toevoegen aan het eind van het Try blok.
Deze logging wordt alleen uitgevoerd als je Try cmdlet slaagt. Je kunt dan je fouten en successen loggen met tijdstempels. De logging laat je nu alles weten wat je script heeft gedaan, succes of falen.
PowerShell is niet je enige optie
Hoewel PowerShell een handig hulpmiddel is voor veel Windows-taken, kan het lastig zijn om het te leren. Het is ook niet voor alles geschikt. Als u systeemonderhoud op uw computer uitvoert of de integriteit van een bestand controleert, is PowerShell handig. Maar als je een script wilt uitvoeren om bestanden van het internet te downloaden of een meer algemene taak wilt uitvoeren, heb je andere opties.
Als u bijvoorbeeld een Unix- of Linux-achtergrond hebt, voelt u zich misschien meer op uw gemak met de bash-shell. Dankzij het Windows Subsystem for Linux kunt u nu eenvoudig bash en andere Linux-tools gebruiken op uw Windows 10-computer. Als dat perfect klinkt voor u, kijk dan niet verder dan onze gids om de bash-shell aan de praat te krijgen op Windows 10.
Kris Wouk is een muzikant, schrijver, en hoe het ook heet als iemand video’s maakt voor het web. Een tech-liefhebber voor zo lang als hij zich kan herinneren, hij heeft zeker favoriete besturingssystemen en apparaten, maar gebruikt zo veel anderen als hij kan toch, gewoon om bij te blijven.
Meer van Kris Wouk