PowerShell 7: Dienste auflisten und filtern — Erklärung und optimierte Skripte

Einleitung

In diesem Beitrag erkläre ich Schritt für Schritt ein kurzes PowerShell-7-Skript, das Dienste auf einem Windows-System auflistet, welche gerade laufen. Ich zeige, was der ursprüngliche Code macht, welche Probleme er hat und liefere mehrere optimierte, sichere und praxisnahe Varianten — inklusive eines robusten Funktions-Skripts, das sich in Windows-Domain-Umgebungen gut einsetzen lässt.

Ursprünglicher Code

$list_all_service = get-service

$list_all_service |
where-object { $_.status -eq ‚Running‘ } |
select-object name, displayname, status |
sort-object name

$list_all_service

Schritt-für-Schritt-Erklärung (einfach verständlich)

1) $list_all_service = get-service
– Get-Service fragt alle Dienste des lokalen Rechners ab und liefert Objekte vom Typ ServiceController.
– Das Ergebnis wird in der Variablen $list_all_service gespeichert.

2) $list_all_service | where-object { $_.status -eq ‚Running‘ } | select-object name, displayname, status | sort-object name
– Der Inhalt der Variablen wird in die Pipeline gegeben.
– Where-Object filtert alle Objekte heraus, deren Property Status den Wert ‚Running‘ hat (also nur laufende Dienste).
– Select-Object reduziert die Ausgabe auf die drei Eigenschaften Name, DisplayName und Status.
– Sort-Object sortiert die Ausgabe nach dem Namen (Name).

3) $list_all_service
– Am Ende wird die Variable erneut ausgegeben — das führt dazu, dass alle Dienste (nicht nur die gefilterten) nochmals unverändert in der Standardansicht angezeigt werden.

Probleme und unerwünschtes Verhalten

– Redundante Ausgabe: Die letzte Zeile ($list_all_service) druckt die vollständige Liste erneut. Vermutlich war das unbeabsichtigt und führt zu Verwirrung.
– Speicher: Falls Sie die vollständige Liste nicht für etwas anderes brauchen, ist das Zwischenspeichern in der Variablen unnötig.
– Lesbarkeit: Der Filter in Where-Object kann kompakter geschrieben werden (PowerShell 7 hat optimierte Syntaxmöglichkeiten).
– Remote-Ausführung: Get-Service unterstützt für moderne, domänenorientierte Admin-Aufgaben nicht immer die beste Remote-Option (besser: Get-CimInstance oder CIM-Session für Remoting und Credentials).

Optimierter Minimal-Code (einzeilig)

Get-Service | Where-Object Status -EQ ‚Running‘ | Select-Object Name, DisplayName, Status | Sort-Object Name

– Kürzere Where-Object-Syntax: Where-Object Status -EQ ‚Running‘ ist performanter und lesbarer in PS7.
– Keine unnötige Zwischenspeicherung.

Robustere Version mit Fehlerbehandlung und Parametern

# Skript: Get-RunningServices.ps1
param(
[string]$ComputerName = ‚localhost‘,
[string]$ExportCsvPath = “
)

try {
# Wenn remote und nicht localhost, Get-CimInstance verwenden (besser für Remoting)
if ($ComputerName -ne ‚localhost‘) {
# Verwende Win32_Service über CIM für Remote-Abfrage
$services = Get-CimInstance -ClassName Win32_Service -ComputerName $ComputerName -ErrorAction Stop |
Where-Object State -EQ ‚Running‘ |
Select-Object @{Name=’Name‘;Expression={$_.Name}}, @{Name=’DisplayName‘;Expression={$_.DisplayName}}, @{Name=’Status‘;Expression={$_.State}} |
Sort-Object Name
}
else {
# Lokale Abfrage mit Get-Service
$services = Get-Service -ErrorAction Stop | Where-Object Status -EQ ‚Running‘ | Select-Object Name, DisplayName, Status | Sort-Object Name
}

# Ausgabe auf Konsole
$services | Format-Table -AutoSize

# Optional: als CSV exportieren
if ($ExportCsvPath) {
$services | Export-Csv -Path $ExportCsvPath -NoTypeInformation -Encoding UTF8
Write-Host „Exportiert: $ExportCsvPath“
}
}
catch {
# Robuste Fehlerbehandlung: detaillierte Meldung und Exit-Code
Write-Error „Fehler beim Abrufen der Dienste auf ‚$ComputerName‘: $_“
exit 1
}

Erklärungen zur robusten Version

– Get-CimInstance vs. Get-Service: Für Remote-Abfragen in Domain-Umgebungen ist Get-CimInstance mit CIM/WinRM stabiler und erlaubt Credentials oder CIM-Sessions. Get-Service kann auf entfernten Systemen Einschränkungen haben.
– ErrorAction Stop: Sorgt dafür, dass fehlerhafte Aufrufe in den catch-Block gehen, statt still zu scheitern.
– Parameter: ComputerName und ExportCsvPath machen das Skript wiederverwendbar.
– Export-Csv: Praktisch, um Ergebnisse zu archivieren oder weiterzuverarbeiten.

Alternative: Funktion mit Credential-Unterstützung

function Get-RunningServices {
param(
[Parameter(Mandatory=$false)]
[string]$ComputerName = ‚localhost‘,

[Parameter(Mandatory=$false)]
[System.Management.Automation.PSCredential]$Credential
)

if ($ComputerName -ne ‚localhost‘ -and $Credential) {
# Beispiel mit New-CimSessionOptions und New-CimSession
$so = New-CimSessionOption -Protocol Wsman
$session = New-CimSession -ComputerName $ComputerName -Credential $Credential -SessionOption $so
try {
$services = Get-CimInstance -CimSession $session -ClassName Win32_Service -Filter „State=’Running'“
return $services | Select-Object @{n=’Name‘;e={$_.Name}}, @{n=’DisplayName‘;e={$_.DisplayName}}, @{n=’Status‘;e={$_.State}} | Sort-Object Name
}
finally {
# Session aufräumen
$session | Remove-CimSession
}
}
else {
return Get-Service | Where-Object Status -EQ ‚Running‘ | Select-Object Name, DisplayName, Status | Sort-Object Name
}
}

Hinweise zur Sicherheit und Berechtigungen

– Für Abfragen von Diensten auf entfernten Rechnern benötigen Sie in der Regel Domänen-Anmeldeinformationen mit passenden Rechten oder ein Konto, das Remote-WMI/CIM abfragen darf.
– Verwenden Sie nach Möglichkeit CIM-Session mit expliziten Credentials statt ungesicherten Klartextübertragungen.
– Testen Sie Skripte zunächst in einer Testumgebung.

Performance-Tipps

– Filtern Sie möglichst früh: Verwenden Sie bei Get-CimInstance bereits einen -Filter (z.B. „State=’Running'“), damit der Server nur relevante Daten sendet.
– Vermeiden Sie unnötige Zwischenspeicherungen großer Listen, wenn Sie nur gefilterte Daten brauchen.

Praxisbeispiele

– Lokale schnelle Ausgabe (Konsole):
Get-Service | Where-Object Status -EQ ‚Running‘ | Select-Object Name, DisplayName, Status | Sort-Object Name

– CSV export für Dokumentation:
Get-Service | Where-Object Status -EQ ‚Running‘ | Select-Object Name, DisplayName, Status | Sort-Object Name | Export-Csv -Path „C:\temp\running-services.csv“ -NoTypeInformation

– Remote (CIM) und nur laufende Dienste abfragen:
Get-CimInstance -ClassName Win32_Service -ComputerName SERVER01 -Filter „State=’Running'“ | Select-Object Name, DisplayName, State

Share this content:

Das hast du vielleicht verpasst

shibiadmin
Datenschutz-Übersicht

Diese Website verwendet Cookies, damit wir dir die bestmögliche Benutzererfahrung bieten können. Cookie-Informationen werden in deinem Browser gespeichert und führen Funktionen aus, wie das Wiedererkennen von dir, wenn du auf unsere Website zurückkehrst, und hilft unserem Team zu verstehen, welche Abschnitte der Website für dich am interessantesten und nützlichsten sind.