Jak sama nazwa wskazuje, PowerShell jest znacznie potężniejszy niż standardowy wiersz poleceń Windows. Z tą mocą wiąże się większa możliwość pomylenia błędów. Jeśli twój skrypt nagle zawiedzie, możesz nie wiedzieć, gdzie zacząć szukać tego, co poszło nie tak. W tym miejscu przydaje się obsługa błędów PowerShella.
Jeśli jesteś zaznajomiony z innymi językami, prawdopodobnie znasz podstawy obsługi błędów, ale są pewne aspekty specyficzne dla PowerShella, które musisz znać. Obsługa błędów w PowerShell składa się z czterech części: parametr Error Action, bloki Try/Catch, parametr Error Variable oraz logowanie.
Obsługa błędów w PowerShellu w prosty sposób
Pierwszym krokiem w obsłudze błędów PowerShella jest poradzenie sobie z czymś, co zatrzymuje skrypt w jego biegu. Jeśli awaria nie wpływa na resztę skryptu, najlepiej po prostu powiedzieć PowerShellowi, aby zignorował błędy i poszedł dalej.
Z drugiej strony, nie zawsze jest jasne, kiedy dany cmdlet rzuca błąd kończący działanie. Niektóre cmdlety zwracają błąd, ale nie zatrzymują skryptu. Może to spowodować, że będziesz czekał na zakończenie skryptu, podczas gdy on wypisuje nonsensy.
W tym miejscu pojawia się parametr -ErrorAction. Używasz go, aby zmusić cmdlet do obsługi błędu w sposób, jaki chcesz. Jeśli modyfikujesz istniejący skrypt, dołączasz go do końca wiersza cmdleta.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Stop
Oczywiście, jeśli używasz cmdleta Get-ChildItem samodzielnie, ten błąd nie ma większego znaczenia. Jednakże, jeśli chcesz zrobić cokolwiek z danymi, dobrze byłoby zatrzymać skrypt, aby wiedzieć, że wyszukiwanie nie powiodło się i dlaczego. Alternatywnie, jeśli wykonujesz wiele wyszukiwań, zmień parametr z Stop na SilentlyContinue, aby skrypt kontynuował wyszukiwanie w przypadku niepowodzenia. Jeśli chcesz zobaczyć, jaki jest błąd, możesz zamiast tego użyć parametru Continue.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction SilentlyContinue
Jeśli wolisz mieć możliwość kontrolowania tego, co dzieje się za każdym razem, gdy skrypt jest uruchamiany, możesz zmienić parametr na Inquire. Kiedy twój cmdlet natrafi na przeszkodę, daje opcje: Yes, Yes For All, Halt Command, Suspend lub Help.
Ta opcja jest nieco bardziej elastyczna, ale oznacza, że błędy powodują, że skrypt czeka na Twoje dane. To jest w porządku, jeśli używasz PowerShell do wysyłania wiadomości e-mail lub innego prostego zadania, ale może to nie być coś, czego chcesz, gdy uruchamiasz długi proces w nocy.
PowerShell Error Handling the PowerShell Powerful Way
Parametr ErrorAction odpowiada na błędy w nieskomplikowany sposób. Jednakże, jeśli szukasz nieco większej kontroli nad błędami, PowerShell nadal ma dla ciebie rozwiązanie. Używając Try/Catch, możemy teraz rozgałęzić skrypt, gdy cmdlet zwróci błąd.
Jak sama nazwa wskazuje, Try/Catch składa się z dwóch części. (Technicznie rzecz biorąc, jest jeszcze trzecia, ale do tego przejdziemy za chwilę) Pierwszą z nich jest sekcja Try. W tej sekcji będziesz uruchamiał swój normalny kod. Nadal będziesz używał parametru -ErrorAction, ale może on być ustawiony tylko jako Stop. Ta flaga zapewnia, że twój cmdlet wywoła Catch—nawet jeśli nie ma błędu kończącego.
Try{
Get-Process "Cortana" -ErrorAction Stop
}
Try może również zapobiec uruchomieniu innych cmdletów, jeśli wyszukiwanie nie powiedzie się. W tym przypadku, jeśli wysyłałeś wyniki Get-Process do Stop-Process, nieudane wyszukiwanie uniemożliwia uruchomienie drugiego cmdleta.
Więc teraz, gdy utworzyłeś blok poleceń cmdlet, co chcesz zrobić, gdy się nie powiedzie? Używając połowy Catch, zamierzasz to zdefiniować.
Catch{
Write-Host "Process Not Found"
}
Podobnie jak w przypadku parametru ErrorAction, gdy robisz coś nieco bardziej złożonego, Catch będzie przydatny do czegoś więcej niż podawanie niepowodzenia w zwykłym języku, zwłaszcza gdy robisz coś nieco bardziej złożonego. (W powyższym przykładzie, niepowodzenie jest wymuszone przez użycie nazwy aplikacji, a nie nazwy procesu). Więc upewnij się, że grasz z blokiem Try, aby utworzyć wyszukiwanie / działanie, którego potrzebujesz. Możesz użyć bloku Catch, aby Twój skrypt wysłał do Ciebie e-mail, jeśli się nie powiedzie.
Trzecia część przydaje się, jeśli chcesz, aby coś zostało uruchomione niezależnie od tego, czy twój cmdlet się powiedzie, czy nie. W tym celu możesz użyć bloku Finally. Dodajesz go po Try i Catch i logujesz się, gdy sekcja twojego skryptu się kończy.
Zmienna Error i logowanie
Twój skrypt kontroluje teraz sposób obsługi błędów i reagowania na nie. Możesz go używać jako zaplanowanego zadania lub przynajmniej uruchamiać go, gdy nie ma Cię przy biurku. Jak jednak można zbadać nieudany skrypt? Dzięki parametrowi -ErrorVariable błędy cmdleta zapisywane są do niestandardowej zmiennej.
Jest to alternatywa dla zmiennej systemowej $Error, która zawiera wszystkie błędy z bieżącej sesji.
Twój cmdlet musi się nieco wydłużyć. Najpierw zdefiniuj zmienną, coś takiego jak $SearchError wystarczy dla tego przykładu. Kiedy wywołujesz SearchError w parmeterze ErrorVariable, nie używasz znaku dolara.
Nawet jeśli wywołujesz zmienną, którą stworzyłeś, ze względu na sposób działania parametru wywołujesz ją bez znaku dolara. Następnie dodaj to na końcu linii.
Get-ChildItem -Path "~\Documents\*.jpg" -Recurse -ErrorAction Continue -ErrorVariable SearchError
Jeśli dodasz + przed nazwą zmiennej, możesz dodać do zmiennej, a nie zastąpić ją całkowicie. W ten sposób uzyskasz takie samo zachowanie jak w przypadku globalnej zmiennej błędu. Zamiast tego, możesz użyć tego wyjścia i Try/Catch do napisania niestandardowego wyjścia i oznaczenia go czasem.
Aby to zadziałało, należy utworzyć plik tekstowy zaraz po ustawieniu zmiennej błędu. Można to zrobić za pomocą polecenia cmdlet New-Item. Możesz użyć opcji Inquire dla parametru ErrorAction. Pozwala to na dodanie do istniejącego dziennika, gdy cmdlet New-Item nie powiedzie się.
$SearchLog = New-Item "~\SearchLog.txt" -type file -ErrorAction Inquire
Teraz, gdy budujesz swój blok Try/Catch, możesz użyć Catch, aby zalogować się do pliku tekstowego. Używasz Get-Date, aby utworzyć znacznik czasu. Formatowanie może być skomplikowane, więc upewnij się, że skopiowałeś to z przykładu.
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"
}
Powtórz to w razie potrzeby dla wszystkich swoich cmdletów, a teraz masz ładny dziennik wszystkich błędów. Jeśli chcesz śledzić rzeczy, które działają z powodzeniem, możesz dodać podobny Add-Content na końcu bloku Try.
To logowanie działa tylko wtedy, gdy twój cmdlet Try powiedzie się. Możesz wtedy rejestrować swoje błędy i sukcesy ze znacznikami czasu. Rejestrowanie teraz pozwala ci wiedzieć wszystko, co zrobił twój skrypt, sukces lub niepowodzenie.
PowerShell nie jest jedyną opcją
Chociaż PowerShell jest przydatnym narzędziem do wielu zadań w systemie Windows, może być trudny do nauczenia. Nie nadaje się też do wszystkiego. Jeśli przeprowadzasz konserwację systemu na swoim komputerze lub sprawdzasz integralność pliku, PowerShell jest przydatny. Z drugiej strony, jeśli chcesz uruchomić skrypt, aby pobrać pliki z Internetu lub wykonać bardziej ogólne zadanie, masz inne opcje.
Na przykład, jeśli pochodzisz z Uniksa lub Linuksa, możesz czuć się bardziej komfortowo, używając powłoki bash. Dzięki podsystemowi Windows dla systemu Linux możesz teraz łatwo korzystać z powłoki bash i innych narzędzi systemu Linux na komputerze z systemem Windows 10. Jeśli brzmi to dla ciebie idealnie, nie szukaj dalej niż nasz przewodnik po uruchomieniu powłoki bash w Windows 10.
Kris Wouk jest muzykiem, pisarzem i jakkolwiek to się nazywa, gdy ktoś tworzy filmy dla sieci. Entuzjasta technologii, odkąd pamięta, zdecydowanie ma ulubione systemy operacyjne i urządzenia, ale używa tak wielu innych, jak tylko może, po prostu po to, aby się nie pogubić.
Więcej od Krisa Wouka