Logging für PowerShell-Skripte

Zur Zeit beschäftige ich mich wieder intensiver mit PowerShell, genauer gesagt mit der Entwicklung von Skripten für wiederkehrenden administrativen Aufgaben. Bisher waren meine Skripte überschaubar und schlicht gehalten. Einen strukturierten Aufbau der Skripts war bisher mehr oder weniger immer gegeben. Mit zunehmer Komplexität und großem Umfang stellt man schnell fest, dass es ohne Logging kaum möglich ist einen vermeidlichen Fehler ohne großen Zeitaufwand zu analyisieren und einzugrenzen.

Daher habe ich mich entschlossen eine Funktion entwerfen, die folgende Anforderungen abdecken soll:

  • Datum und Zeit an dem der  jeweilige Befehl/Aktion ausgeführt wird.
  • Verschiedene Loglevel mit dazugehörigen Farben in der Powershell Konsole.
  • Ausgabe der Meldungen sowohl in der Powershell Konsole als auch in eine Protokolldatei mit einem Befehl (Vermeidung von Overhead im Quellcode).
  • Benutzername und Domäne bzw. Computername, auf dem das Skript gelaufen ist, sollen festgehalten werden.
  • Dateiname als auch Speicherort soll über Variable änderbar sein, ohne großartig den Quellcode anpassen zu müssen.

Folgendes Powershell-Schnipsel ist entstanden:

#----------------------------------------------------------[Declarations]----------------------------------------------------------
# function Write-Log
[string] $strLogfilePath = "C:\Temp"
[string] $strLogfileDate = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
[string] $strLogfileNamePrefix = "Log_"
[string] $strLogfileName = $($strLogfileNamePrefix + $strLogfileDate + ".log")
[string] $strLogfile = $strLogfilePath + "\" + $strLogfileName

#-----------------------------------------------------------[Functions]------------------------------------------------------------

function Write-Log {
    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory=$true,
            Position=0)]
        [ValidateNotNullOrEmpty()]
        [string] $LogText = "",

        [Parameter(Mandatory=$false)]
        [ValidateNotNullOrEmpty()]
        [ValidateSet('Info','Success','Warning','Error')]
        [string] $LogStatus= "Info",

        [Parameter(Mandatory=$false)]
        [switch] $Absatz,

        [Parameter(Mandatory=$false)]
        [switch] $EventLog
    )

    [string] $strLogdate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    [string] $strTextColor = "White"
    [string] $strLogFileAbsatz = ""
    [string] $strLogFileHeader = ""

    # Add a header to logfile, if the logfile not exist
    If ( -not (Test-Path $strLogfile) ) {
        $strLogFileHeader = "$("#" * 75)`n"
        $strLogFileHeader += "{0,-21} {1,0}" -f "# Skript:", "$($MyInvocation.ScriptName)`n"
        $strLogFileHeader += "{0,-21} {1,0}" -f "# Startzeit:", "$(Get-Date -Format "dd.MM.yyyy HH:mm:ss")`n"
        $strLogFileHeader += "{0,-21} {1,0}" -f "# Startzeit:", "$(Get-Date -Format "dd.MM.yyyy HH:mm:ss")`n"
        $strLogFileHeader += "{0,-21} {1,0}" -f "# Ausführendes Konto:", "$([Security.Principal.WindowsIdentity]::GetCurrent().Name)`n"
        $strLogFileHeader += "{0,-21} {1,0}" -f "# Computername:", "$env:COMPUTERNAME`n"
        $strLogFileHeader += "$("#" * 75)`n"

        Write-Host $strLogFileHeader
        Add-Content -Path $strLogfile -Value $strLogFileHeader -Encoding UTF8
    }
   

    switch($LogStatus) {
        Info {
            $strTextColor = "White"
        }
        Success {
            $strTextColor = "Green"
        }
        Warning {
            $strTextColor = "Yellow"
        }
        Error {
            $strTextColor = "Red"
        }
    }

    # Add an Absatz if the parameter is True
    if($Absatz) {
        [string] $strLogFileAbsatz = "`r`n"
    }

    #Format the text output
    $LogText = "{0,-20} - {1,-7} - {2,0}" -f "$strLogdate", "$LogStatus", "$LogText $strLogFileAbsatz"

    # Write output to powershell console
    Write-Host $LogText -ForegroundColor $strTextColor

    # Write output to logfile
    Add-Content -Path $strLogfile -Value $LogText -Encoding UTF8

    # Add Logfile to local Eventlog of the operating system 
    if($EventLog) {
        Write-EventLog -LogName 'Windows PowerShell' -Source "Powershell" -EventId 0 -Category 0 -EntryType $LogStatus -Message $LogText
    }

}


#-----------------------------------------------------------[Execution]------------------------------------------------------------

Write-Log -LogText "Das ist ein Test." -LogStatus Info
Write-Log -LogText "Das ist ein Test." -LogStatus Success
Write-Log -LogText "Das ist ein Test." -LogStatus Warning
Write-Log -LogText "Das ist ein Test." -LogStatus Error -Absatz
Write-Log -LogText "Das ist ein Test."
#Write-Log -LogText ""

Quelle: GitHub

Die Funktion nutze ich nun knapp ein halbes Jahr. Bisher keine Informationen vermissen lassen. Tut was es soll.

Viel Spaß beim Ausprobieren. 🙂