en av de viktigaste delarna av alla bra PowerShell script är felhantering. Även i det kortaste skriptet, att kunna hantera fel hjälper till att säkerställa att en oväntad händelse inte kommer att fortsätta att förstöra det system du arbetar med. Ta exemplet nedan. Varje vecka i vårt provföretag (MyCompany.Com) mänskliga resurser kommer att ladda upp en lista som berättar vem som ska ha tillgång till Kostnadsdatabasen., Om ett namn inte finns i listan från HR kommer vi att ta bort det från gruppen och att användaren inte längre kommer att kunna logga utkostnadsanspråk:
Nu kan du se var det här kommer att gå fel. En vecka HR inte komma runt för att ladda upp listan eller, precis som vi är på väg att komma åt listan, filservern dör. Plötsligt kastar PowerShell ett fel på Get-Content cmdlet och $ AuthorizedUser-variabeln förblir tom. Eftersom vårt skript inte hanterar fel fortsätter det att köras och på mycket kort tid har det tagit bort alla användare från vår kostnadsgrupp., Ganska snart börjar ilskna telefonsamtal översvämningar i och livet blir lite mindre glad. Sättet att undvika allt detta är att fånga fel och sedan hantera händelsen som orsakade dem (som i detta fall är Stoppa manuset och har ett rop på någon i HR).
avslutande och icke-avslutande fel
en av de viktigaste sakerna att veta när fånga fel är att endast vissa fel kan fångas som standard. Fel kommer i två typer-avslutande och icke-avslutande. Ett avslutande fel är ett fel som stoppar en funktion eller operation., Om du gör ett syntaxfel eller får slut på minne är det ett avslutande fel. Avslutande fel kan fångas och hanteras. Icke-avslutande fel tillåter Powershell att fortsätta och vanligtvis kommer från cmdlets eller andra hanterade situationer. Under normala omständigheter kan de inte fångas av försök-fångst-slutligen. Get-Content-felet i exemplet ovan är ett icke-avslutande fel.
behandla icke-avslutande fel som att avsluta
Så hur fångar du ett icke-avslutande fel? I grund och botten säger du till PowerShell att behandla det som avslutande. För att göra detta använder du parametern ErrorAction., Varje PowerShell-cmdlet stöder ErrorAction. Genom att ange-ErrorAction stopp i slutet av en cmdlet du se till att eventuella fel det kastar behandlas som avslutande och kan fångas. I vårt exempel ovan kommer vi att ändra vår Get-Content-linje till:
$AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop
behandla alla fel som att avsluta
det är också möjligt att behandla alla fel som att avsluta med hjälp av erroractionpreference-variabeln. Du kan göra detta antingen för skriptet du arbetar med eller för hela PowerShell-sessionen. För att ställa in det i ett skript, gör den första raden $ErrorActionPreference = Stop., För att ställa in den för sessionen, skriv $ErrorActionPreference = stopp vid PowerShell-konsolen.
fånga ett avslutande fel
När du har sett till att felet du försöker fånga kommer att behandlas som avslutande, kan du bygga ett försök fångstblock runt kommandot (eller kommandon) som kan orsaka felet. Det första steget är att omge den del av skriptet som kan kasta felet med ett Försöksblock. I vårt exempel blir Get-Content-raden:
Try{ $AuthorizedUsers= Get-Content \\ FileServer\HRShare\UserList.txt -ErrorAction Stop}
omedelbart efter Försöksblocket måste du placera ett fångstblock för att hantera felet., Fångstblocket nås endast om ett avslutande fel inträffar, annars ignoreras det. I vårt exempel kommer vi att maila en administratör för att säga att det har skett ett fel och sedan stoppa skriptet. Vår Get-Content-linje är nu:
åtkomst till Felposten
När du är inne i ett fångstblock kan du komma åt felposten, som lagras i den aktuella Objektvariabeln $_. Felposter har olika användbara egenskaper, men den viktigaste du vill komma åt är$_.Undantag., Undantag är vad vi verkligen hanterar här när vi fångar och hanterar fel-undantag är den oväntade händelsen som orsakade felet (felposten i sig är faktiskt bara en omslag för att presentera undantaget till PowerShell-användaren). Det är undantaget att vi fångar och undantaget som innehåller all riktigt användbar information om problemet. Om det fanns ett ytterligare underliggande problem som orsakade vårt undantag, registreras det också på$_.undantag.innerexception (och så vidare – nästa underliggande undantag lagras på$_.undantag.- lnnerexception.,innerexception etc.). För syftet med vårt exempel kommer vi att använda $_.Undantag för att lägga lite extra information i vårt meddelande e-post, med hjälp av $_.Undantag.Meddelande och$_.Undantag.ItemName egenskaper:
fånga specifika undantag
nu, som vårt exempel står vi fånga eventuella fel som uppstår under filen läsa och hantera dem alla på samma sätt. Du kan dock fånga specifika undantag och hantera dem annorlunda, men – och det är en stor men – bara om det ursprungliga felet avslutas., Eftersom Get-Content cmdlet kastar icke-avslutande fel (som vi bara har behandlat som avslutande med hjälp av ErrorAction)kan vi inte specifikt fånga de olika undantagen som cmdlet kan kasta. Detta är ett inslag i PowerShell och gäller för alla icke-avslutande fel, oavsett ErrorActionPreference och kan inte ändras. Ändå kan vi hantera andra terminerande undantag, till exempel ett minnesfel, som kan dyka upp under läsoperationen. I detta exempel kommer vi att göra det.,
Du fångar specifika termineringsfel genom att ange undantagsnamnet omedelbart efter fångst sökordet. I vårt exempel vill vi fånga ett System.OutOfMemory undantag och, om vi får en, kommer att ta no nonsense tillvägagångssätt för att starta om datorn omedelbart. Vi kommer också att inkludera ett allmänt fångstblock efter att vår fil inte hittats block för att fånga alla andra undantag:
slutligen, med hjälp av äntligen
den sista delen av Försöksfångsten är äntligen det äntligen blocket. Detta måste definieras omedelbart efter Fångstblocket och körs varje gång, oavsett om det fanns ett fel eller inte., På så sätt kan du utföra åtgärder som måste göras oavsett om en operation lyckas eller misslyckas. I vårt exempel kommer vi att logga in att en fil lästes försökte. Vår Get-Content linje ser nu ut: