Som navnet antyder, er PowerShell meget mere kraftfuld end den almindelige Windows-kommandoprompt. Med denne magt følger en større mulighed for forvirrende fejl. Hvis dit script pludselig fejler, ved du måske ikke, hvor du skal begynde at lede efter, hvad der gik galt. Det er her, at PowerShells fejlhåndtering er praktisk.
Hvis du er bekendt med andre sprog, kender du sikkert de grundlæggende principper for fejlhåndtering, men der er nogle aspekter, der er specifikke for PowerShell, som du skal kende. Der er fire dele af fejlhåndteringen i PowerShell: parameteren Error Action (fejlhandling), Try/Catch-blokke, parameteren Error Variable (fejlvariabel) og logning.
PowerShell-fejlhåndtering på den nemme måde
Det første skridt i håndteringen af PowerShell-fejl er at håndtere noget, der stopper dit script i dets spor. Hvis fejlen ikke påvirker resten af dit script, er det måske bedst blot at bede PowerShell om at ignorere fejl og gå videre.
På den anden side er det ikke altid klart, hvornår en given cmdlet kaster en afsluttende fejl. Nogle cmdlets returnerer en fejl, men stopper ikke dit script. Det kan betyde, at du skal vente på, at dit script afsluttes, mens det udsender noget vrøvl.
Det er her, at parameteren -ErrorAction kommer ind i billedet. Du bruger den til at tvinge en cmdlet til at håndtere fejlen på den måde, du ønsker. Hvis du ændrer et eksisterende script, føjer du den til slutningen af cmdlet-linjen.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop
Det er klart, at hvis du bruger cmdletten Get-ChildItem alene, gør denne fejl ikke meget for dig. Hvis du imidlertid ønsker at gøre noget med dataene, vil det være godt at stoppe scriptet, så du ved, at søgningen mislykkedes og hvorfor. Hvis du udfører flere søgninger, kan du alternativt ændre parameteren fra Stop til SilentlyContinue, så scriptet fortsætter, hvis en søgning mislykkes. Hvis du ønsker at se, hvad fejlen er, kan du i stedet bruge Continue som parameter.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction SilentlyContinue
Hvis du hellere vil have mulighed for at styre, hvad der sker, hver gang dit script kører, kan du ændre den til Inquire. Når din cmdlet støder på en forhindring, giver den muligheder: Ja, Ja til alle, Stop kommandoen, Suspender eller Hjælp.
Denne mulighed er lidt mere fleksibel, men betyder, at fejl får dit script til at vente på dit input. Det er fint, hvis du bruger PowerShell til at sende en e-mail eller en anden simpel opgave, men det er måske ikke noget, du ønsker, når du kører en lang proces om natten.
PowerShell-fejlhåndtering på den kraftfulde måde
Parameteren ErrorAction håndterer dine fejl på en ukompliceret måde. Hvis du imidlertid ønsker lidt mere kontrol over fejl, kan PowerShell stadig dække dig. Ved hjælp af Try/Catch kan vi nu forgrene scriptet, når cmdlets returnerer en fejl.
Som navnet antyder, består Try/Catch af to dele. (Der er teknisk set en tredje, men det kommer vi til om et øjeblik.) Den første er Try-delen. Du kommer til at køre din normale kode i denne sektion. Du vil stadig bruge parameteren -ErrorAction, men den kan kun indstilles som Stop. Dette flag sikrer, at din cmdlet udløser Catch—-selv om den ikke har en afsluttende fejl.
Try{
Get-Process "Cortana" -ErrorAction Stop
}
Try kan også forhindre andre cmdlets i at køre, hvis søgningen mislykkes. I dette tilfælde, hvis du sendte Get-Process-resultaterne til Stop-Process, forhindrer en mislykket søgning den anden cmdlet i at køre.
Så nu, hvor du har oprettet en try-blok af cmdlets, hvad vil du så gøre, når den mislykkes? Ved hjælp af Catch halvdelen skal du definere dette.
Catch{
Write-Host "Process Not Found"
}
Ligesom med ErrorAction-parameteren vil Catch, når du laver noget lidt mere komplekst, være nyttig til mere end at give en almindelig fejlmeddelelse i almindelig sprogbrug, især når du laver noget lidt mere komplekst. (I eksemplet ovenfor er fejlen fremtvunget ved at bruge app-navnet og ikke procesnavnet). Så sørg for at lege med Try-blokken for at skabe en søgning/handling du har brug for. Du kan bruge Catch-blokken til dit script til at sende dig en e-mail, hvis det mislykkes.
Den tredje del er praktisk, hvis du vil have noget til at køre, uanset om din cmdlet lykkes eller ej. Til dette kan du bruge Finally-blokken. Du tilføjer denne efter Try og Catch og logger, når et afsnit af dit script slutter.
Fejlvariablen og logning
Dit script styrer nu, hvordan det håndterer fejl, og hvordan det reagerer på dem. Du kan bruge det som en planlagt opgave eller i det mindste køre det, når du ikke er ved dit skrivebord. Men hvordan kan du undersøge et mislykket script? Med parameteren -ErrorVariable skriver din cmdlets fejl til en brugerdefineret variabel.
Dette er et alternativ til systemvariablen $Error, som indeholder alle fejlene fra den aktuelle session.
Din cmdlet skal blive lidt længere. Først skal du definere en variabel, noget som $SearchError vil være tilstrækkeligt i eksemplet. Når du kalder SearchError i parameteret ErrorVariable, skal du ikke bruge dollartegnet.
Selv om du kalder en variabel, du har oprettet, kalder du den på grund af den måde, parameteren fungerer på, uden dollartegnet. Derefter tilføjer du det til slutningen af linjen.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Continue -ErrorVariable SearchError
Hvis du tilføjer et + foran variabelnavnet, kan du tilføje til variablen i stedet for at erstatte den helt og holdent. Det giver dig den samme opførsel som den globale fejlvariabel. I stedet kan du bruge dette output og Try/Catch til at skrive brugerdefineret output og tidsstemple det.
For at få dette til at fungere skal du oprette en tekstfil lige efter, at du har indstillet fejlvariablen. Gør dette med cmdletten New-Item. Du kan eventuelt bruge indstillingen Inquire til parameteren ErrorAction. Dette giver dig mulighed for at tilføje til en eksisterende log, når New-Item-cmdletten mislykkes.
$SearchLog = New-Item "~\SearchLog.txt" -type file -ErrorAction Inquire
Når du nu opbygger din Try/Catch-blok, kan du bruge Catch til at logge til en tekstfil. Du bruger Get-Date til at oprette tidsstemplet. Formateringen kan være vanskelig, så du skal sørge for at kopiere den fra eksemplet.
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"
}
Gentag dette efter behov for alle dine cmdlets, og du har nu en fin logbog over eventuelle fejl. Hvis du ønsker at spore ting, der kører med succes, kan du tilføje en lignende Add-Content i slutningen af Try-blokken.
Denne logning kører kun, når din Try cmdlet lykkes. Du kan derefter logge dine fejl og succeser med tidsstempler. Logningen lader dig nu vide alt, hvad dit script har gjort, uanset om det er lykkedes eller mislykkedes.
PowerShell er ikke din eneste mulighed
Selv om PowerShell er et praktisk værktøj til masser af Windows-opgaver, kan det være svært at lære. Det er heller ikke velegnet til alt. Hvis du skal foretage systemvedligeholdelse på din computer eller kontrollere integriteten af en fil, er PowerShell praktisk. Hvis du derimod ønsker at køre et script til at downloade filer fra internettet eller en mere generel opgave, har du andre muligheder.
Hvis du f.eks. kommer fra en Unix- eller Linux-baggrund, vil du måske være mere komfortabel med bash-shell. Takket være Windows Subsystem for Linux kan du nu nemt bruge bash og andre Linux-værktøjer på din Windows 10-computer. Hvis det lyder perfekt for dig, skal du ikke lede længere end til vores guide til at få bash-shell’en til at køre på Windows 10.
Kris Wouk er musiker, forfatter og hvad det nu hedder, når nogen laver videoer til nettet. Han har været teknisk entusiast så længe han kan huske, og han har helt sikkert favorit-operativsystemer og -enheder, men bruger så mange andre som muligt alligevel, bare for at holde sig opdateret.
Mere fra Kris Wouk