3 min read
Skriptabbruch verhindern: PowerShell-Fehler clever behandeln
Da $error eine globale Variable ist, solltest du in Erwägung ziehen, eine eigene Protokollierungsvariable für die...
PowerShell-Erfolgsrezepte – die Profi-Tipps für effektives Scripting
Da $error eine globale Variable ist, solltest du in Erwägung ziehen, eine eigene Protokollierungsvariable für die Fehlerbehandlung zu verwenden, damit du andere Nutzer nicht beeinträchtigst (und umgekehrt).
Wenn PowerShell auf eine nicht behandelte Ausnahme stößt, wird diese in der globalen $error-Variablen gespeichert. Diese kann für die Fehlerbehandlung verwendet werden. Hier ist ein typischer Code:
# Fehlerprotokoll löschen (clear error log)
$error.Clear()
# Fehlermeldungen vor dem Nutzer verbergen (hide error messages from the user)
$ErrorActionPreference = 'SilentlyContinue'
# führe Cmdlet-Aktionen aus, d.h. finde Protokolldateien (perform cmdlet actions)
$result = Get-ChildItem -Path $env:windir -Depth 1 -Filter *.log
# führe weitere Aktionen aus, d. h. greife auf einen Dienst zu, der nicht existiert (perform more actions)
$service = Get-Service -Name notThere
# Wiederherstellen der Standardfehleraktion (restore default error action)
$ErrorActionPreference = 'Continue'
# Fehler im Nachhinein überprüfen (check errors after the fact)
$errorCount = $error.Count
Write-Host "There were $errorCount errors."
# Ausgabe von Fehlerdetails (output error details)
$error.CategoryInfo | Select-Object -Property Category, TargetName
Diese Art der Fehlerbehandlung eignet sich in der Regel für Cmdlets, die ihre Arbeit beenden und nicht abgebrochen werden sollen.
Da es sich bei $error jedoch um eine globale Variable handelt, kann das Löschen dieser Variable Auswirkungen auf andere Benutzer haben. Ebenso kann die eigene Fehlerprotokollierung von Befehlen beeinflusst werden, die von Drittanbieter-Modulen verwendet werden (da diese die Variable ebenfalls jederzeit löschen können).
Aus diesen Gründen ist es sicherer, eine eigene Variable für die Fehlerprotokollierung zu verwenden. Beachte, dass der folgende Code $error nicht beeinflusst:
# führe Cmdlet-Aktionen aus, d. h. finde Protokolldateien (perform cmdlet actions)
$result = Get-ChildItem -Path $env:windir -Depth 1 -Filter *.log -ErrorAction SilentlyContinue -ErrorVariable myErrors
# führe weiterer Aktionen aus, d. h. greife auf einen Dienst zu, der nicht existiert (perform more actions)
$service = Get-Service -Name notThere -ErrorAction SilentlyContinue -ErrorVariable +myErrors
# überprüfe Fehler im Nachhinein (check errors after the fact)
$errorCount = $myErrors.Count
Write-Host "There were $errorCount errors."
# Ausgabe von Fehlerdetails (output error details)
$myErrors.CategoryInfo | Select-Object -Property Category, TargetName
Stattdessen gibt der Parameter ‑ErrorVariable den Namen der eigenen Variablen an, die für die Fehlerprotokollierung verwendet werden soll, in diesem Fall "myErrors". Dadurch wird das Cmdlet angewiesen, die neue Variable $myErrors zu generieren. Wenn der Variablenname durch "+" angehängt wird, verwendet das Cmdlet eine vorhandene Variable, sodass die Fehler mehrerer Cmdlets in dieser Variablen protokolliert werden können.
Wenn du alle Fehler aller Cmdlets in deinem Skript auf diese Weise protokollieren möchtest, kannst du $ErrorActionPreference in "SilentlyContinue" ändern und $PSDefaultParameterValues verwenden, um ‑ErrorVariable immer für alle Cmdlets zu verwenden:
# clear error variable if it exists from a previous run
$variableExists = Get-Variable -Name myErrors -Scope 0 -ErrorAction Ignore
if ($variableExists) { Remove-Variable -Name myErrors }
# add private error logging to all cmdlets
$ErrorActionPreference = 'SilentlyContinue'
$PSDefaultParameterValues.Add('*:ErrorVariable', '+myErrors')
# perform cmdlet actions, i.e. find log files
$result = Get-ChildItem -Path $env:windir -Depth 1 -Filter *.log
# perform more actions, i.e. access a service that does not exist
$service = Get-Service -Name notThere
# check errors after the fact
$errorCount = $myErrors.Count
Write-Host "There were $errorCount errors."
# output error details
$myErrors.CategoryInfo | Select-Object -Property Category, TargetName
Entfessele das volle Potenzial von PowerShell mit unserem praktischen Poster. Egal, ob frischer Einsteiger oder erfahrener Profi, dieser Spickzettel ist so konzipiert, dass du schnell die wichtigsten und am häufigsten verwendeten Cmdlets findest.
Das Poster ist zum Download und in Papierform erhältlich.
Okt 17, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Da $error eine globale Variable ist, solltest du in Erwägung ziehen, eine eigene Protokollierungsvariable für die...
Okt 30, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Verabschiede dich von fest codierten Pfaden und Einstellungen! Vereinfache deine PowerShell-Skripte, indem du...
Okt 24, 2024 by Aleksandar Nikolić und Dr. Tobias Weltner
Hier kommt die nächste Strategie zur Fehlerbehandlung, nachdem wir zuvor die Echtzeit und verzögerte Fehlerbehandlung...
Tobias Weltner und Aleksandar Nikolić haben gemeinsam die Blogpost-Reihe „Tobias&Aleksandars PowerShell-Tipps“ verfasst. Deshalb möchten wir euch beide hier vorstellen:
----------------------------
Aleksandar Nikolić ist ein Microsoft Azure MVP und Mitbegründer von PowerShellMagazine.com, der ultimativen Online-Ressource für PowerShell-Enthusiasten. Mit über 18 Jahren Erfahrung in der Systemadministration ist er ein angesehener Trainer und Redner, der rund um den Globus reist, um sein Wissen und seine Fähigkeiten über Azure, Entra und PowerShell weiterzugeben. Er hat auf IT-Veranstaltungen wie Microsoft Ignite, ESPC, NIC, CloudBrew, NTK und der PowerShell Conference Europe gesprochen.
----------------------------
Tobias ist ein langjähriger Microsoft MVP und war von Anfang an an der Entwicklung von PowerShell beteiligt. Er hat die PowerShell IDE „ISESteroids“ erfunden, zahlreiche Bücher über PowerShell für Microsoft Press und O'Reilly geschrieben, die PowerShell Conference EU (psconf.eu) gegründet und trägt derzeit als Mitglied der „Microsoft Cmdlet Working Group“ zur Weiterentwicklung der PowerShell bei. Tobias gibt sein Wissen als Berater in Projekten und als Trainer in Inhouse-Schulungen für zahlreiche Unternehmen und Agenturen in ganz Europa weiter.