En av de viktigste delene av en god PowerShell script er feil håndtering. Selv i de korteste script, blir i stand til å håndtere feil bidrar til å sikre at en uventet hendelse vil ikke gå med på å ødelegge systemet du jobber på. Ta eksempelet nedenfor. Hver uke i utvalget vårt selskap (MyCompany.Com) Menneskelige Ressurser kommer til å laste opp en liste som forteller oss hvem som skal ha tilgang til Utgifter database., Hvis navnet ikke er i listen fra HR-vi kommer til å fjerne den fra gruppen, og at brukeren vil ikke lenger være i stand til å logge reiseregning:
Nå, du kan se hvor dette kommer til å gå galt. En uke HR ikke komme seg rundt for å laste opp på listen, eller, akkurat som vi er i ferd med å få tilgang til listen, fil server dør. Plutselig PowerShell kaster en feil på Get-Innhold cmdlet og $AuthorizedUser variabel forblir tom. Fordi våre skriptet ikke håndtere feil, det fortsetter å kjøre, og i en veldig kort tid, og det har fjernet alle bruker fra vår egen gruppe., Ganske snart den rasende telefonsamtaler starte flom i og livet blir litt mindre fornøyd. Den måten å unngå dette er å fange feilene og deretter håndtere hendelsen som forårsaket dem (som i dette tilfellet er stoppe script og har en rope på noen i HR).
Avslutning, og Ikke-Terminerende Feil
En av de viktigste tingene å vite når å fange feil er at bare enkelte feil kan bli fanget opp av standard. Feil kommer i to typer – avslutning, og ikke-terminerende. En avslutning feil er en feil som vil stoppe en funksjon eller drift., Hvis du gjør en syntaks feil eller går tom for minne, som er en avslutning feil. Avslutning av feil kan bli fanget og håndtert. Ikke-terminerende feil tillate Powershell til å fortsette og kommer vanligvis fra cmdlets eller andre klarte situasjoner. Under normale omstendigheter de ikke kan bli fanget av Try-Catch-Finally. Get-Innhold feil i eksemplet ovenfor er en ikke-terminerende feil.
Behandling av Ikke-Terminerende Feil som Avslutning
Så hvordan kan du fange et Ikke-Terminerende feil? I utgangspunktet, du fortelle PowerShell til å behandle det som avslutning. For å gjøre dette må du bruke ErrorAction parameter., Hver PowerShell-cmdlet støtter ErrorAction. Ved å spesifisere -ErrorAction Stopp på slutten av en cmdlet du sørge for at eventuelle feil den kaster behandles som avslutning, og kan bli fanget. I vårt eksempel ovenfor, hvor vi kommer til å endre vår Get-Innhold linjen:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
Behandle Alle Feil som Avslutning
Det er også mulig å behandle alle feil som avslutning med ErrorActionPreference variabel. Du kan gjøre dette enten for skriptet ditt er som arbeider med eller for hele PowerShell-sesjon. For å sette det i et skript, kan du gjøre den første linjen $ErrorActionPreference = Stopp., For å sette det for-økt, skriver du $ErrorActionPreference = Stopp på PowerShell-konsollen.
Fange en Avslutning Feil
Når du har sørget for at feil du prøver å fange kommer til å bli behandlet som avslutning, kan du bygge en Prøve Catch-blokk rundt kommandoen (eller kommandoer) som kan forårsake feil. Den første fasen er å omringe den delen av skriptet som kan kaste feil med en Try-blokk. I vårt eksempel Get-Innhold blir linjen:
Try{ $AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop}
Rett etter Try-blokk, må du sette en Catch-blokk for å håndtere feil., Catch-blokken er bare tilgjengelig hvis en avslutning feil oppstår, ellers blir det ignorert. I vårt eksempel skal vi en e-post admin for å si at det har vært en feil og så stoppe script. Vår Get-Innhold line er nå:
få Tilgang til Feilen ta opp
Når du er inne i en catch-blokken du kan få tilgang til feil post, som er lagret i gjeldende objekt-variable, $_. Feilregistreringer har ulike nyttige egenskaper, men den viktigste vil du ønsker å få tilgang er $_.Unntak., Unntak er hva vi egentlig å gjøre med her, så vi kan ta imot og håndtere feil – unntakene er uventet hendelse som forårsaket av feil (feil-rekord i seg selv er faktisk egentlig bare en wrapper for å presentere unntak til PowerShell bruker). Det er unntaket at vi er fanger og unntak som inneholder alle virkelig nyttig informasjon om problemet. Hvis det var enda et underliggende problem som forårsaket vår unntak, det er også opp til $_.unntak.innerexception (og så videre – neste underliggende unntak er lagret på $_.unntak.innerexception.,innerexception etc.). For formålene i vårt eksempel skal vi bruke $_.Unntak for å sette litt ekstra informasjon i våre varsling om e-post, ved å bruke $_.Unntak.Melding og $_.Unntak.ItemName egenskaper:
Fange Spesielle Unntak
Nå, i vårt eksempel står vi fange opp eventuelle feil som kan oppstå under den filen du lese og håndtere alle av dem på samme måte. Du kan imidlertid ta spesifikke unntak, og håndtere dem på en annen måte, men – og det er et stort men – bare hvis den opprinnelige feilen er å avslutte., Fordi Få-Innhold cmdlet kaster ikke-terminerende feil (som vi har kun behandlet som avslutning med ErrorAction) vi kan ikke fange de ulike unntakene som cmdleten kan kaste. Dette er en funksjon av PowerShell og gjelder for alle ikke-terminerende feil, uavhengig av ErrorActionPreference og kan ikke endres. Likevel, vi kan dele med andre avslutte unntak, for eksempel en tom for minne feil, som kan beskjære opp under operasjon. For formålene i dette eksemplet som er hva vi vil gjøre.,
Du fange bestemt å avslutte feil ved å angi unntak navn umiddelbart etter Fangst søkeord. I vårt eksempel vi ønsker å fange et System.OutOfMemory unntak, og hvis vi får en, vil ta no nonsense tilnærming for å restarte maskinen umiddelbart. Vi vil også inneholde en generell catch-blokken etter vår fil ikke funnet blokk for å fange alle andre unntak:
til Slutt, ved Hjelp av Endelig
Den siste delen av Prøve å Fange til Slutt er det Endelig blokk. Dette må være definert umiddelbart etter Fangst blokkere og kjøres hver gang, uansett om det var feil eller ikke., På denne måten kan du utføre handlinger som må gjøres uavhengig av om en operasjon lykkes eller mislykkes. I vårt eksempel har vi tenkt til å logge på at filen du lese ble forsøkt. Vår Get-Innhold line nå ser ut som: