Wie man Windows-Diensten mit PowerShell überprüft und startet

Es ist auschlaggebend, dass Sie den Windows-Dienststatus überprüfen und das gute Funktionieren von Diensten auf Windows-Computern aufrechterhalten können. PowerShell ermöglicht dies Ihnen, damit Sie für einen reibungslosen Betrieb in jeder IT-Umgebung sorgen. Dienste, die so eingestellt sind, dass sie automatisch starten, aber nicht ausgeführt werden, können zu Leistungsproblemen, ungeplanten Netzwerkausfällen und betrieblichen Ineffizienzen führen.

An dieser Stelle kommen PowerShell-Skripte ins Spiel, die eine robuste und automatisierte Methode zur Verwaltung und Überwachung von Windows-Diensten bieten. In diesem Blogbeitrag wird ein PowerShell-Skript vorgestellt, mit dem automatische Dienste, die derzeit nicht ausgeführt werden, gemeldet und gestartet werden, mit Ausnahme von Diensten, für die ein ‘Verzögerter Start’ oder ‘Ausgelöster Start’ festgelegt ist.

Kontext

Für IT-Expert:innen und Managed Service Provider (MSPs) hat der reibungslose Betrieb von Diensten höchste Priorität. Windows-Dienste können manchmal aus verschiedenen Gründen nicht gestartet werden, zum Beispiel aufgrund von Konfigurationsproblemen, Konflikten oder begrenzten Systemressourcen.

Dieses Skript befasst sich mit der Notwendigkeit eines systematischen Ansatzes zur Identifizierung und zum Neustart von Diensten, die laufen sollten, aber nicht funktionieren. Durch die Automatisierung dieses Prozesses können IT-Teams Zeit sparen und das Risiko menschlichen Versagens verringern.

Das Skript zur Überprüfung des Status von Windows-Diensten

#Requires -Version 5.1

<#
.SYNOPSIS
    Reports on or starts services for Automatic Services that are not currently running. Services set as 'Delayed Start' or 'Trigger Start' are ignored.
.DESCRIPTION
    Reports on or starts services for Automatic Services that are not currently running. Services set as 'Delayed Start' or 'Trigger Start' are ignored.
.EXAMPLE
    (No Parameters)
    
    Matching Services found!

    Name    Description                                         
    ----    -----------                                         
    SysMain Maintains and improves system performance over time.

PARAMETER: -IgnoreServices "ExampleServiceName"
    A comma separated list of service names to ignore.

PARAMETER: -StartFoundServices
    Attempts to start any services found matching the criteria.

.NOTES
    Minimum OS Architecture Supported: Windows 10, Windows Server 2016
    Release Notes: Initial Release
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use.
    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. 
    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. 
    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. 
    Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. 
    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. 
    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. 
    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>

[CmdletBinding()]
param (
    [Parameter()]
    [String]$IgnoreServices,
    [Parameter()]
    [Switch]$StartFoundServices = [System.Convert]::ToBoolean($env:startFoundServices)
)

begin {
    # Replace script parameters with form variables
    if($env:servicesToExclude -and $env:servicesToExclude -notlike "null"){ $IgnoreServices = $env:servicesToExclude }

    # Get the last startup time of the operating system.
    $LastBootDateTime = Get-CimInstance -ClassName Win32_OperatingSystem | Select-Object -ExpandProperty LastBootUpTime
    if ($LastBootDateTime -gt $(Get-Date).AddMinutes(-15)) {
        $Uptime = New-TimeSpan $LastBootDateTime (Get-Date) | Select-Object -ExpandProperty TotalMinutes
        Write-Host "Current uptime is $([math]::Round($Uptime)) minutes."
        Write-Host "[Error] Please wait at least 15 minutes after startup before running this script."
        exit 1
    }

    # Define a function to test if the current user has elevated (administrator) privileges.
    function Test-IsElevated {
        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
        $p = New-Object System.Security.Principal.WindowsPrincipal($id)
        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
    }

    $ExitCode = 0
}
process {
    # Check if the script is running with Administrator privileges.
    if (!(Test-IsElevated)) {
        Write-Host -Object "[Error] Access Denied. Please run with Administrator privileges."
        exit 1
    }

    # Define a string of characters that are invalid for service names.
    $InvalidServiceNameCharacters = "\\|/|:"
    # Create a list to hold the names of services to ignore.
    $ServicesToIgnore = New-Object System.Collections.Generic.List[string]

    # If there are services to ignore and they are separated by commas, split the string into individual service names.
    if ($IgnoreServices -and $IgnoreServices -match ",") {
        $IgnoreServices -split "," | ForEach-Object {
            # Check each service name for invalid characters or excessive length.
            if ($_.Trim() -match $InvalidServiceNameCharacters) {
                Write-Host "[Error] Service Name contains one of the invalid characters '\/:'. $_ is not a valid service to ignore."
                $ExitCode = 1
                return
            }

            if (($_.Trim()).Length -gt 256) {
                Write-Host "[Error] Service Name is greater than 256 characters. $_ is not a valid service to ignore. "
                $ExitCode = 1
                return
            }

            # Add valid services to the ignore list.
            $ServicesToIgnore.Add($_.Trim())
        }
    }
    elseif ($IgnoreServices) {
        # For a single service name, perform similar validation and add if valid.
        $ValidService = $True

        if ($IgnoreServices.Trim() -match $InvalidServiceNameCharacters) {
            Write-Host "[Error] Service Name contains one of the invalid characters '\/:'. '$IgnoreServices' is not a valid service to ignore. "
            $ExitCode = 1
            $ValidService = $False
        }

        if (($IgnoreServices.Trim()).Length -gt 256) {
            Write-Host "[Error] Service Name is greater than 256 characters. '$IgnoreServices' is not a valid service to ignore. "
            $ExitCode = 1
            $ValidService = $False
        }

        if ($ValidService) {
            $ServicesToIgnore.Add($IgnoreServices.Trim())
        }
    }

    # Create a list to hold non-running services that are set to start automatically.
    $NonRunningAutoServices = New-Object System.Collections.Generic.List[object]
    Get-Service | Where-Object { $_.StartType -like "Automatic" -and $_.Status -ne "Running" } | ForEach-Object {
        $NonRunningAutoServices.Add($_)
    }

    # Remove services from the list that have triggers or are set to delayed start,
    if ($NonRunningAutoServices.Count -gt 0) {
        $TriggerServices = Get-ChildItem -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\*\*" -ErrorAction SilentlyContinue | Where-Object { $_.Name -match "TriggerInfo" }
        $TriggerServices = $TriggerServices | Select-Object -ExpandProperty PSParentPath | Split-Path -Leaf
        foreach ($TriggerService in $TriggerServices) {
            $NonRunningAutoServices.Remove(($NonRunningAutoServices | Where-Object { $_.ServiceName -match $TriggerService })) | Out-Null
        }

        $DelayedStartServices = Get-ItemProperty -Path "Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\*" | Where-Object { $_.DelayedAutoStart -eq 1 }
        $DelayedStartServices = $DelayedStartServices | Select-Object -ExpandProperty PSChildName
        foreach ($DelayedStartService in $DelayedStartServices) {
            $NonRunningAutoServices.Remove(($NonRunningAutoServices | Where-Object { $_.ServiceName -match $DelayedStartService })) | Out-Null
        }
    }

    # Remove explicitly ignored services from the list of non-running automatic services.
    if ($ServicesToIgnore.Count -gt 0 -and $NonRunningAutoServices.Count -gt 0) {
        foreach ($ServiceToIgnore in $ServicesToIgnore) {
            if ($NonRunningAutoServices.ServiceName -contains $ServiceToIgnore) {
                $NonRunningAutoServices.Remove(($NonRunningAutoServices | Where-Object { $_.ServiceName -match [Regex]::Escape($ServiceToIgnore) })) | Out-Null
            }
        }
    }

    # If there are still non-running automatic services left, display their names.
    # Otherwise, indicate no stopped automatic services were detected.
    if ($NonRunningAutoServices.Count -gt 0) {
        Write-Host "Matching Services found!"

        # Add Description to report.
        $ServicesReport = New-Object System.Collections.Generic.List[object]
        $NonRunningAutoServices | ForEach-Object {
            $Description = Get-CimInstance -ClassName Win32_Service -Filter "Name = '$($_.ServiceName)'" | Select-Object @{
                Name       = "Description"
                Expression = {
                    $Characters = $_.Description | Measure-Object -Character | Select-Object -ExpandProperty Characters
                    if ($Characters -gt 100) {
                        "$(($_.Description).SubString(0,100))..."
                    }
                    else {
                        $_.Description
                    }
                }
            }
            $ServicesReport.Add(
                [PSCustomObject]@{
                    Name = $_.ServiceName
                    Description = $Description | Select-Object -ExpandProperty Description
                }
            )
        }

        # Output report to activity log.
        $ServicesReport | Sort-Object Name | Format-Table -Property Name,Description -AutoSize | Out-String | Write-Host
    }
    else {
        Write-Host "No stopped automatic services detected!"
    }

    # Exit the script if there are no services to start or if starting services is not requested.
    if (!$StartFoundServices -or !($NonRunningAutoServices.Count -gt 0)) {
        exit $ExitCode
    }

    # Attempt to start each non-running automatic service up to three times.
    # Log success or error messages accordingly.
    $NonRunningAutoServices | ForEach-Object {
        Write-Host "`nAttempting to start $($_.ServiceName)."
        $Attempt = 1
        while ($Attempt -le 3) {
            Write-Host -Object "Attempt: $Attempt"
            try {
                $_ | Start-Service -ErrorAction Stop
                Write-Host -Object "Successfully started $($_.ServiceName)."
                $Attempt = 4
            }
            catch {
                Write-Host -Object "[Error] $($_.Exception.Message)"
                if ($Attempt -eq 3) { $ExitCode = 1 }
            }
            $Attempt++
        }
    }
    
    exit $ExitCode
}
end {
    
    
    
}

 

Greifen Sie auf über 300 Skripte im NinjaOne Dojo zu.

Zugang erhalten

Detailansicht

Schauen wir uns das Skript genauer an, um zu verstehen, wie es Schritt für Schritt funktioniert.

  1. Skriptinitialisierung und Parameter: Das Skript beginnt mit der Definition seines Zwecks und seiner Parameter. Er akzeptiert zwei optionale Parameter: -IgnoreServices, eine durch Komma getrennte Liste von Diensten, die ignoriert werden sollen, und -StartFoundServices, ein Schalter zum Starten der nicht laufenden Dienste, die die Kriterien erfüllen.
  2. Prüfung der Betriebszeit: Bevor das Skript fortfährt, prüft es die Betriebszeit des Systems, um sicherzustellen, dass es seit mindestens 15 Minuten in Betrieb ist. Dies verhindert Probleme im Zusammenhang mit Diensten, die nach einem Neustart möglicherweise nicht genügend Zeit hatten, um ordnungsgemäß zu starten.
  3. Prüfung der Berechtigungen: Das Skript stellt sicher, dass es mit Administratorrechten ausgeführt wird, weil das Stoppen und Starten von Diensten erhöhte Berechtigungen erfordert.
  4. Validierung von Diensten: Die zu ignorierenden Dienste werden validiert, um zu gewährleisten, dass sie keine ungültigen Zeichen enthalten und ihre Namen nicht übermäßig lang sind.
  5. Identifizierung nicht laufender Dienste: Das Skript sammelt eine Liste von Diensten, die automatisch gestartet werden sollen, aber derzeit nicht ausgeführt werden. Anschließend werden Dienste herausgefiltert, die auf ‘verzögerten Start’ eingestellt sind oder Auslösebedingungen haben.
  6. Berichterstattung und Maßnahmen: Wenn nicht laufende Dienste gefunden werden, meldet das Skript diese. Wenn der Schalter -StartFoundServices gesetzt ist, wird versucht, jeden dieser Dienste zu starten, wobei Erfolge und Fehler protokolliert werden.

Potenzielle Anwendungsfälle

Fallstudie:

Stellen Sie sich vor, eine IT-Expert:in verwaltet ein Netzwerk von Windows-Servern, auf denen verschiedene wichtige Anwendungen gehostet werden. Eines Tages melden die Benutzer:innen Probleme beim Zugriff auf eine wichtige Anwendung. Die IT-Expert:in führt dieses PowerShell-Skript aus, das feststellt, dass der Dienst der Anwendung, der auf automatischen Start eingestellt ist, nicht ausgeführt wird. Das Skript versucht, den Dienst neu zu starten, um das Problem schnell zu beheben und den normalen Betrieb wiederherzustellen.

Vergleiche

Dieses Skript bietet einen optimierten, automatisierten Ansatz im Vergleich zur manuellen Überprüfung jedes Dienstes über das MMC-Snap-In oder zur Verwendung anderer, weniger gezielter Skripte. Alternative Methoden, wie etwa die Verwendung vom Task Scheduler zur Überwachung von Diensten, können komplexer und schwieriger zu warten sein.

FAQs

F: Kann dieses Skript auch auf älteren Windows-Versionen verwendet werden?

A: Das Skript ist für Windows 10, Windows Server 2016 und neuer konzipiert. Die Kompatibilität mit älteren Versionen kann Anpassungen erfordern.

F: Was passiert, wenn ein Dienst nicht gestartet werden kann?

A: Das Skript versucht, jeden Dienst bis zu dreimal zu starten und protokolliert Fehler, wenn dies nicht gelingt.

F: Kann ich mehrere Dienste von der Prüfung ausschließen?

A: Ja, verwenden Sie den Parameter -IgnoreServices mit einer durch Komma getrennten Liste von Dienstnamen.

Folgen

Die Automatisierung der Überwachung und Verwaltung von Windows-Diensten erhöht die betriebliche Effizienz und verringert die Wahrscheinlichkeit von Ausfallzeiten. Die Gewährleistung, dass kritische Dienste immer laufen, kann die Zuverlässigkeit und Sicherheit des Systems verbessern.

Empfehlungen

  • Regelmäßige Überwachung: Planen Sie die Ausführung des Skripts in regelmäßigen Abständen mithilfe vom Task Scheduler, um für eine kontinuierliche Überwachung zu sorgen.
  • Protokollierung: Implementieren Sie zusätzliche Protokollierungs-Mechanismen, um einen Verlauf der vom Skript durchgeführten Aktionen zu erhalten.
  • Prüfung: Testen Sie das Skript in einer Staging-Umgebung, bevor Sie es in der Produktion einsetzen.

Abschließende Überlegungen

Durch die Automatisierung der Verwaltung von Windows-Diensten können IT-Expert:innen für eine höhere Betriebszeit und Zuverlässigkeit ihrer Systeme sorgen. Für diejenigen, die ihren IT-Betrieb weiter rationalisieren möchten, bieten Tools wie NinjaOne umfassende Lösungen für die Überwachung, Verwaltung und Automatisierung verschiedener Aspekte der IT-Infrastruktur, die die Möglichkeiten dieses Skripts ergänzen.

Nächste Schritte

Der Aufbau eines effizienten und effektiven IT-Teams erfordert eine zentralisierte Lösung, die als einheitliches Tool zur Bereitstellung von IT-Dienstleistungen fungiert. NinjaOne ermöglicht es IT-Teams, alle Geräte zu überwachen, zu verwalten, zu sichern und zu unterstützen, unabhängig vom Standort, ohne dass eine komplexe Infrastruktur vor Ort erforderlich ist.

Erfahren Sie mehr über NinjaOne Remote Script Deployment, sehen Sie sich eine Live-Tour an oder starten Sie Ihre kostenlose Testversion unserer NinjaOne Plattform.

Kategorien:

Das könnte Sie auch interessieren

×

Sehen Sie NinjaOne in Aktion!

Mit dem Absenden dieses Formulars akzeptiere ich die Datenschutzerklärung von NinjaOne.

NinjaOne Allgemeine Geschäftsbedingungen für Skripte

Indem Sie unten auf die Schaltfläche “Ich akzeptiere” klicken, erklären Sie Ihr Einverständnis mit den folgenden rechtlichen Bedingungen sowie mit unseren Nutzungsbedingungen:

  • Eigentumsrechte: NinjaOne besitzt und wird weiterhin alle Rechte, Titel und Interessen an dem Skript (einschließlich des Urheberrechts) behalten. NinjaOne gewährt Ihnen eine eingeschränkte Lizenz zur Nutzung des Skripts in Übereinstimmung mit diesen rechtlichen Bedingungen.
  • Einschränkung der Nutzung: Sie dürfen das Skript nur für Ihre legitimen persönlichen oder internen Geschäftszwecke verwenden und es nicht an Dritte weitergeben.
  • Verbot der Wiederveröffentlichung: Sie sind unter keinen Umständen berechtigt, das Skript in einer Skriptbibliothek, die einem anderen Softwareanbieter gehört oder von diesem kontrolliert wird, erneut zu veröffentlichen.
  • Gewährleistungsausschluss: Das Skript wird “wie gesehen” und “wie verfügbar” bereitgestellt, ohne jegliche Garantie. NinjaOne gibt keine Versprechen oder Garantien, dass das Skript frei von Fehlern ist oder dass es Ihre speziellen Bedürfnisse oder Erwartungen erfüllt.
  • Risikoübernahme: Die Verwendung des Skripts erfolgt auf eigene Gefahr. Sie erkennen an, dass die Nutzung des Skripts mit bestimmten Risiken verbunden ist, und Sie verstehen und übernehmen jedes dieser Risiken.
  • Verzicht und Freigabe: Sie machen NinjaOne nicht für nachteilige oder unbeabsichtigte Folgen verantwortlich, die sich aus Ihrer Nutzung des Skripts ergeben, und Sie verzichten auf alle gesetzlichen oder billigkeitsrechtlichen Rechte oder Rechtsmittel, die Sie gegen NinjaOne im Zusammenhang mit Ihrer Nutzung des Skripts haben könnten.
  • EULA: Wenn Sie ein NinjaOne-Kunde sind, unterliegt Ihre Nutzung des Skripts dem für Sie geltenden Endbenutzer-Lizenzvertrag (EULA).