Obsługę błędów można realizować w powershell korzystając z intrukcji try/catch/finally. Często do obsługi błędu wystarczy konstrukcja:
try { GWMI Win32_bios -ComputerName 'blablacomp'-ea Stop } catch { echo "general exception" }
Ale zdarza się, że z jakiegoś powodu w bloku try znajduje się kilka instrukcji, które mogły spowodować błąd i w zależności od tego jaki błąd został napotkany będzie należało wykonać inną czynność w bloku catch.
Oto przykład takiej konstrukcji:
try { del c:\temp\blablabla.txt -ea stop GWMI Win32_bios -ComputerName 'blablacomp'-ea Stop } catch [System.Runtime.InteropServices.COMException] { echo "com exception" } catch [System.Management.Automation.ItemNotFoundException] { echo "file not found exception" } catch { echo "general exception" }
Tym razem, jeśli dojdzie do błędu, to w zależności od tego jaki to błąd, zostanie uruchomiona inna sekcja catch. Nazwy w nawiasach kwadratowych są nazwami typów różncyh rodzajów wyjątków zgłaszanych przez uruchamiane w bloku try polecenia. Jeśli doszło by do niewymienionego tutaj błedu to wykonany zostanie standardowy blok catch
Pozostaje tylko jeden duży problem. Skąd u licha wziąć wykaz możliwych do spotkania exception? Szczerze mówiąc nie wiem… może nawet nie ma miejsca w którym wszystkie byłyby spisane, ale jeśli już masz jakiś błąd to na pewno uda ci się ustalić jaki to exception. Zastosuj poniższą metodę:
Najpierw sprowokuj błąd, np tak:
gwmi win32_bios -ComputerName 'asf'
Na ekranie wyświetlił się jakiś komunikat o błędzie ale ciągle nie ma tam poszukiwanej informacji, za to jest ona w zmiennej $Error[0]. Dlatego w kolejnym kroku przejrzyj właściwości tej zmiennej, np. tak:
$Error[0] | fl * -Force
Na ekranie zobaczysz coś podobnego:
writeErrorStream : True
PSMessageDetails :
Exception : System.Runtime.InteropServices.COMException (0x800706BA): The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
at System.Management.ThreadDispatch.Start()
at System.Management.ManagementScope.Initialize()
at System.Management.ManagementObjectSearcher.Initialize()
at System.Management.ManagementObjectSearcher.Get()
at Microsoft.PowerShell.Commands.GetWmiObjectCommand.BeginProcessing()
TargetObject :
CategoryInfo : InvalidOperation: (:) [Get-WmiObject], COMException
FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 0}
Podkreślona część to właśnie informacja o rodzaju zgłoszonego wyjątku Oto kolejny przykład:
del c:\ajdahsdhaO
$Error[0] | fl * -Force
i wynik:
writeErrorStream : True
PSMessageDetails :
Exception : System.Management.Automation.ItemNotFoundException: Cannot find path 'C:\ajdahsdhaO’ because it does not exist.
at System.Management.Automation.LocationGlobber.ExpandMshGlobPath(String path, Boolean allowNonexistingPaths, PSDriveInfo drive,
ContainerCmdletProvider provider, CmdletProviderContext context)
at System.Management.Automation.LocationGlobber.ResolveDriveQualifiedPath(String path, CmdletProviderContext context, Boolean
allowNonexistingPaths, CmdletProvider& providerInstance)
at System.Management.Automation.LocationGlobber.GetGlobbedMonadPathsFromMonadPath(String path, Boolean allowNonexistingPaths,
CmdletProviderContext context, CmdletProvider& providerInstance)
at Microsoft.PowerShell.Commands.RemoveItemCommand.ProcessRecord()
TargetObject : C:\ajdahsdhaO
CategoryInfo : ObjectNotFound: (C:\ajdahsdhaO:String) [Remove-Item], ItemNotFoundException
FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
ErrorDetails :
InvocationInfo : System.Management.Automation.InvocationInfo
ScriptStackTrace : at <ScriptBlock>, <No file>: line 1
PipelineIterationInfo : {0, 1}
Znasz lepszą metodę? Podziel się z nami!