Gorodenkoff - stock.adobe.com

So überwachen Sie Server einfach mit PowerShell

In diesem Artikel zeigen wir, wie Sie ein Serverüberwachungs-Framework mit PowerShell einrichten, um benutzerdefinierte Prüfungen zur Überwachung Ihrer Umgebung durchzuführen.

Je größer Ihre Serverumgebung wird, desto mehr Unterstützung benötigen Sie für die Überwachung und das Vermeiden von Problemen.

Es gibt viele Angebote für die Überwachung von Servern und das Erstellen von Berichten. Manchmal bietet sich jedoch der Rückgriff auf einfachere Varianten mit Bordmitteln an. Bei der Überwachung mit PowerShell nutzen Sie systemeigene Funktionen von Windows, um Skripte zu erstellen, die Ihre Systeme überprüfen und Berichte regelmäßig aktualisieren.

In diesem Artikel erklären wir, wie Sie regelmäßige Serverprüfungen mit automatisch generierten Berichten in benutzerdefinierten Intervallen einrichten. Dieses Tutorial basiert zu Lernzwecken auf PowerShell 5.1, die Durchführung mit der aktuellen Version – PowerShell 7 – ist jedoch ebenso möglich.

Serverüberwachung mit PowerShell

PowerShell bietet eine Vielzahl von Möglichkeiten für die Serverüberwachung. Dieses Tutorial konzentriert sich jedoch auf einige wichtige Kernfunktionen, um ein möglichst einfaches Framework zu demonstrieren:

  • Festplattenplatz: PowerShell überprüft den verfügbaren Platz auf lokalen Festplatten und sendet eine Warnung, sobald der Anteil unter einen festgelegten Prozentsatz sinkt.
  • Version des Betriebssystems: PowerShell überprüft, ob das Betriebssystem neuer als die festgelegte Version ist.
  • Ablaufende Zertifikate: PowerShell erstellt eine Liste aller Zertifikate, die innerhalb eines festgelegten Zeitraums ablaufen werden.
  • Lizenzen: PowerShell überwacht den Status von Lizenzen und meldet nicht-lizenzierte Komponenten.

Skriptstruktur für die Serverüberwachung mit PowerShell

Die Grundidee der hier vorgestellten Serverüberwachungs-Strategie besteht darin, eine Reihe Prüfungen auf einem oder mehreren Servern durchzuführen, die Ergebnisse zu speichern und dann diese Ergebnisse zu überprüfen. Zu diesem Zweck werden wir die folgenden Funktionen im PowerShell-Skript erstellen.

  • Invoke-ServerCheck. Diese Funktion legt die Prüfungen fest und die Rechner, auf denen diese ausgeführt werden sollen, und exportiert dann die Ergebnisse in eine XML-Datei.
  • New-ServerReport. Diese Funktion stellt die Informationen in diesen XML-Dateien nach festgelegten Gesichtspunkten zu täglichen oder monatlichen Berichten zusammen.

Aufbau eines Skripts für die Serverprüfung

Es gibt viele Möglichkeiten, ein Skript für Serverprüfungen zu strukturieren. In diesem Tutorial werden alle Prüfungen in einer Hashtabelle abgelegt, die Skriptblöcke verwendet. Dadurch lässt sich der Code auf den angeforderten Computern leichter ausführen, entweder lokal oder remote.

Zusätzlich verwendet das Skript den condition-Schlüssel und den zugehörigen Skriptblock, um zu melden, ob die Prüfung positiv oder negativ ausgefallen ist. Jede Bedingung sollte einen booleschen Wert zurückgeben.

Neue Prüfungen fügen Sie hinzu, indem Sie einen neuen Schlüssel auf der obersten Ebene mit check- und condition-Unterschlüssel hinzufügen. Beides sind Skriptblöcke, die der Invoke-Befehl innerhalb der Funktion Invoke-ServerCheck ausführt.

$Checks = @{
   'OSVersion' = @{
     'Check' = {
       Get-CimInstance Win32_OperatingSystem | Select-Object Caption, Version, ServicePackMajorVersion, OSArchitecture
     }
     'Condition' = {$_.Version -LT 6.2}
   }
   'Certificates' = @{
     'Check' = {
       Get-ChildItem -Path 'Cert:' -Recurse -ExpiringInDays 30 | Select-Object Subject, NotAfter
     }
     'Condition' = {$Result.Count -GT 0}
   }
   'DiskSpace' = @{
     'Check' = {
       Get-CIMInstance -Class 'Win32_logicaldisk' -Filter "DriveType = '3'" | Select-Object -Property DeviceID, @{L='FreeSpaceGB';E={"{0:N2}" -f ($_.FreeSpace /1GB)}}, @{L="Capacity";E={"{0:N2}" -f ($_.Size/1GB)}}
     }
     'Condition' = { ($Result | Where-Object { (($_.FreeSpaceGB / $_.Capacity) * 100) -LT 10 }).Count -GT 0 }
   }
   'License' = @{
     'Check' = {
       Enum Licensestatus {
         Unlicensed      = 0
         Licensed        = 1
         OOBGrace        = 2
         OOTGrace        = 3
         NonGenuineGrace = 4
         Notification    = 5
         ExtendedGrace   = 6
       }
        
       Get-CimInstance -ClassName SoftwareLicensingProduct -Filter "PartialProductKey IS NOT NULL" | Select-Object Name, ApplicationId, @{N='LicenseStatus'; E={[LicenseStatus]$_.LicenseStatus} }
     }
         'Condition' = {($Results | Where-Object LicenseStatus -NE 'Licensed').Count -EQ 0}
   } 
 }

Die Funktion Invoke-ServerCheck

Die Funktion Invoke-ServerCheck übernimmt den Großteil der Serverüberwachung mit PowerShell. Diese Funktion nimmt eine Reihe von Prüfungen aus der Variablen $Checks auf, dann wird jeder Satz von Prüfungen auf den Servern oder dem lokalen Computer ausgeführt.

Das Skript führt die folgenden Schritte aus:

  • wiederholt jede Prüfung der $Checks-Variable;
  • führt den Invoke-Befehl auf dem Skriptblock über den Checks-Schlüssel aus;
  • speichert das Ergebnis mit der Variablen $CheckResults; und
  • speichert das XML der Variablen $Output im vorgegebenen Pfad. Das erleichtert das Anpassen dieser Variablen in späteren Funktionen.

Function Invoke-ServerCheck {
   [CmdletBinding()]
 
   Param(
       [Parameter(Position = 0, Mandatory = $True)]$Checks,
       [Parameter(Position = 1, ValueFromPipeline = $True)]$ComputerName,
       [Parameter(Position = 2)]$Path = $Env:TEMP
   )
 
   Process {
     If ($ComputerName) {
       $Computer = $ComputerName
     } Else {
       $Computer = $Env:COMPUTERNAME
     }
 
     $CheckResults = @()
 
     $Checks.GetEnumerator() | ForEach-Object {
       Write-Host "Running Check, $($_.Key), on $Computer" -ForegroundColor 'Green'
 
       $Params = @{
         "ScriptBlock"  = $_.Value.Check
         "Verbose"      = $MyInvocation.BoundParameters.Verbose
       }
 
       If ($ComputerName) {
         $Params.Add('ComputerName', $Computer)
       }
 
       $Result = Invoke-Command @Params
 
       $CheckResults += ,[PSCustomObject]@{
         "Check"     = $_.Key
         "Result"    = $Result
         "Condition" = (Invoke-Command -ScriptBlock $_.Value.Condition -ArgumentList $Result)
       }
     }
 
     $Output = [PSCustomObject]@{
       "Server"  = $Computer
       "Results" = $CheckResults
     }
 
     $FileName = "ServerResults-{0}-{1}.xml" -F $Computer, (Get-Date -Format "yyyy_MM_dd_HH_mm_ss")
 
     Export-Clixml -Path (Join-Path -Path $Path -ChildPath $FileName) -InputObject $Output
   }
 }

Als nächstes sorgen Sie dafür, dass PowerShell einen Bericht ausgibt, aus dem hervorgeht, welche Prüfungen der angegebene Server bestanden oder nicht bestanden hat.

Die Funktion New-ServerReport

Um besser nachvollziehen zu können, welche Prüfungen auf welchem Server durchgeführt wurden, verwenden Sie die Funktion New-ServerReport.

Die Funktion führt die folgenden Schritte aus:

  • Sie sucht nach XML-Dateien, die den Namen ServerResults tragen;
  • führt Prüfungen durch, ob ein täglicher oder monatlicher Bericht existiert;
  • entscheidet anhand des Wertes CreationTime, ob alle Dateien des jeweiligen Tages oder der letzten 30 Tage gezogen werden sollen;
  • gruppiert die Ergebnisse anhand der geprüften Server und gibt sie in einer Tabelle aus; und
  • speichert die Ergebnisse zur späteren Ansicht in einer CSV-Datei.

Function New-ServerReport {
   [CmdletBinding()]
 
   Param(
       [Parameter(Position = 0)]
       [ValidateSet('Daily','Monthly')]
       [String]$Type = 'Daily',
       [Parameter(Position = 1)]$Path = $Env:TEMP,
       [Parameter(Position = 2)]$ReportPath = $Env:TEMP
   )
 
   Process {
     $Files = Get-ChildItem -Path $Path -Filter '*.xml' | Where-Object Name -Match 'ServerResults'
 
     Switch ($Type) {
       'Daily' {   
         $Results = $Files | Where-Object 'CreationTime' -GT (Get-Date -Hour 0 -Minute 00 -Second 00)
 
         $ResultArray = @()
 
         $Results | ForEach-Object {
           $ResultArray += ,[PSCustomObject]@{
             'Results'  = (Import-Clixml -Path $_.FullName)
             'DateTime' = $_.CreationTime
           }
         }
        
         $Report = $ResultArray | Foreach-Object {
           $DateTime = $_.DateTime
        
           $_.Results | Group-Object -Property 'Server' | Foreach-Object {
             $Server = $_.Name
        
             $_.Group.Results | ForEach-Object {
               $Object = [PSCustomObject]@{
                 "Server"   = $Server
                 "Check"    = $_.Check
                 "Result"   = $_.Condition
                 "DateTime" = $DateTime
               }
        
               $Object
             }
           }
         }
 
         $FileName = "ServersReport-{0}.csv" -F (Get-Date -Format "yyyy_MM_dd_HH_mm_ss")
 
         $Report | Export-CSV -Path (Join-Path -Path $ReportPath -ChildPath $FileName) -NoTypeInformation
 
         $Report
 
         Break
       }
 
       'Monthly' {
         $Results = $Files | Where-Object 'CreationTime' -GT (Get-Date).AddDays(-30)
 
         $ResultArray = @()
 
         $Results | ForEach-Object {
           $ResultArray += ,[PSCustomObject]@{
             'Results'  = (Import-Clixml -Path $_.FullName)
             'DateTime' = $_.CreationTime
           }
         }
        
         $Report = $ResultArray | Foreach-Object {
           $DateTime = $_.DateTime
        
           $_.Results | Group-Object -Property 'Server' | Foreach-Object {
             $Server = $_.Name
        
             $_.Group.Results | ForEach-Object {
               $Object = [PSCustomObject]@{
                 "Server"   = $Server
                 "Check"    = $_.Check
                 "Result"   = $_.Condition
                 "DateTime" = $DateTime
               }
        
               $Object
             }
           }
         }
 
         $FileName = "ServersReport-{0}.csv" -F (Get-Date -Format "yyyy_MM_dd_HH_mm_ss")
 
         $Report | Export-CSV -Path (Join-Path -Path $ReportPath -ChildPath $FileName) -NoTypeInformation
 
         $Report
 
         Break
       }
     }
   }
 }

Durchführen der Serverüberwachung mit PowerShell-Skripten

Am einfachsten verwenden Sie dieses Skript, indem Sie die zu prüfenden Server hinzufügen und dann den Befehl New-ServerReport verwenden, um festzustellen, welche Prüfungen im Laufe der Zeit durchgeführt wurden:

# Perform Checks on Requested Servers
 @("Server1","Server2","Server3") | Invoke-ServerCheck
 # Generate Daily Report
 New-ServerReport

Ein modulares Skript erleichtert die Überwachung mit PowerShell

Wenn Sie in PowerShell ein modulares Framework für die Serverüberwachung erstellen, erleichtern Sie sich den Überblick und die Kontrolle in Ihrer Serverumgebung. Sie können dieses Skript ganz einfach um eine Vielzahl zusätzlicher Abfragen erweitern, abhängig von Ihren Bedürfnissen und der Komplexität Ihrer Umgebung.

Mit den neuen plattformübergreifenden Fähigkeiten von PowerShell 7 können Sie diese Prüfungen auch auf Linux-Systeme ausdehnen, um zum Beispiel notwendige betriebssystemspezifische Aktualisierungen durchzuführen.

Erfahren Sie mehr über Serverbetriebssysteme

ComputerWeekly.de
Close