Für die korrekte Überwachung und das Debugging ist es wichtig zu wissen, was ein Skript macht.
Sie können ein Skript auf viele verschiedene Arten überwachen und welche Art Sie wählen, hängt meistens davon ab, wie das Skript ausgeführt wird. Wenn ein Skript interaktiv aufgerufen wird, das heißt direkt von der Konsole durch Techniken wie Write-Verbose, Write-Information oder Write-Host, dann ist das nützlich, weil jeder Befehl Nachrichten auf der Konsole anzeigen kann während das Skript läuft. Aber was kann man machen, wenn das Skript durch einen geplanten Task oder einen anderen Prozess, bei dem kein auf einen Bildschirm starrender Mensch involviert ist, aufgerufen wird? In dem Fall muss ein anderes Niveau an Überwachung hinzugefügt werden. Eine Log-Datei ist eine hervorragende Methode, ein Skript zu überwachen, das nicht interaktiv läuft.
Es gibt verschiedene Arten, Text in eine Textdatei in PowerShell zu schreiben und welche Art verwendet wird, hängt ganz von dem Entwickler ab. Bevor Sie Ihre eigene Logging-Funktion erstellen, sollten Sie jedoch einige Dinge beachten.
- Alle Zeilen im Log müssen strukturierter Inhalt sein - keine wild herumfliegenden Text-Nachrichten.
- Jeder Log-Eintrag sollte einen Zeit-Stempel haben.
- Ein Schweregrad oder anderer „Tag“ sollte benutzt werden, um später die Informationen einfach in der Log-Datei filtern zu können.
Nun sehen Sie Schritt für Schritt, wie man eine PowerShell-Funktion erstellen kann, die sich in jedes Skript einfügen lässt. Da diese Funktion für verschiedene Skripts verfügbar sein soll, erstelle ich ein PS1 Skript, um die Funktion zu hinterlegen. Der Name der Funktion ist Write-Log.
Write-Log.ps1
function Write-Log {
[CmdletBinding()]
param()
}
Diese Logging-Funktion schreibt eine einzige Log-Zeile jedes Mal, wenn sie gerufen wird. Jede Zeile im Log hat zwei Attribute, die sich ändern je nachdem, was man aufzeichnen möchte; Nachricht und Schweregrad – diese fügt man als Parameter zu der Funktion hinzu.
function Write-Log {
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information','Warning','Error')]
[string]$Severity = 'Information'
)
}
Sie sehen, dass der Wert des Severity-Parameters auf drei Möglichkeiten beschränkt wurde. Damit kann man sicher sein, dass dieses Feld immer auf einen dieser drei Schweregrade gesetzt wird. Wenn diese Parameter ersteinmal erstellt sind, benutzt man CSV, um eine strukturierte Log-Datei zu erstellen. Dadurch kann man die Log-Datei schnell in einem Tabellenkalkulationsprogramm aufrufen und wenn nötig die Daten sortieren. Sie sehen unten, dass immer die Zeit mit hinzugefügt wurde. Dies ist kein Parameter, weil es immer die Zeit sein wird, zu der die Funktion ausgeführt wurde.
function Write-Log {
[CmdletBinding()]
param(
[Parameter()]
[ValidateNotNullOrEmpty()]
[string]$Message,
[Parameter()]
[ValidateNotNullOrEmpty()]
[ValidateSet('Information','Warning','Error')]
[string]$Severity = 'Information'
)
[pscustomobject]@{
Time = (Get-Date -f g)
Message = $Message
Severity = $Severity
} | Export-Csv -Path "$env:Temp\LogFile.csv" -Append -NoTypeInformation
}
Das war schon alles für die Write-Log-Funktion. Man kann diese jetzt zu jedem beliebigen Skript hinzufügen, solange man sie vorher per Dot-Sourcing einbindet. Wenn das Write-Log.ps1-Skript sich im gleichen Ordner wie das Skript befindet, von dem man es aufruft, würde man es folgendermaßen per Dot-Sourcing einbinden:
Script.ps1
. "$PSScriptRoot\Write-Log.ps1
Wenn das Skript erst einmal die Funktion kennt, kann man sie so oft wie nötig in dem Skript aufrufen.
$foo = $false
if ($foo) {
Write-Log -Message 'Foo was $true' -Severity Information
} else {
Write-Log -Message 'Foo was $false' -Severity Error
}
Die Informationen werden dann in der Log-Datei gespeichert und das würde so aussehen:
PS> Import-Csv "$env:Temp\LogFile.csv"
Time Message Severity
---- ------- --------
5/13/2017 2:19 PM Foo was $false Error