PowerShell-Grundlagen für Windows-Admins
PowerShell-Grundlagen für Windows-Admins: Cmdlet-Prinzip, Pipeline mit Objekten, Discovery, Execution Policy, erstes Skript, Module und Fehlerbehandlung auf Windows Server 2022/2025.

Diese Anleitung bringt dir die PowerShell-Grundlagen für Windows-Admins bei, mit denen du Windows Server 2022/2025 effizient verwaltest. Du lernst das Cmdlet-Prinzip Verb-Nomen, die objektbasierte Pipeline, Discovery über Get-Help und Get-Command, das richtige Setzen der Execution Policy, dein erstes Skript mit Parametern, das Nachladen von Modulen aus der PSGallery und kurze Fehlerbehandlung mit try/catch. Das ist der Einstieg, auf dem die vertiefenden Active-Directory-, Hyper-V- und DHCP-Anleitungen aufbauen.
Voraussetzungen
- Windows Server 2022 oder 2025 (On-Premises) mit administrativem Konto. Windows PowerShell 5.1 ist ab Server 2016 bzw. Windows 10/11 bereits vorinstalliert.
- Eine als Administrator gestartete Konsole für systemweite Einstellungen (z. B.
Set-ExecutionPolicy -Scope LocalMachineoderUpdate-Help). - Optional Internetzugang für PowerShell 7, Hilfeinhalte (
Update-Help) und Module aus der PSGallery (benötigt TLS 1.2 oder höher). - Für die weiterführenden Themen die passenden Rollen/Features bzw. RSAT-Tools (AD, Hyper-V, DHCP).
Schritt 1: Version prüfen und PowerShell 7 installieren
Zuerst klärst du, womit du arbeitest. Windows PowerShell 5.1 startet als powershell.exe und basiert auf dem .NET Framework (nur Windows, wird nur noch mit Sicherheitsfixes versorgt). PowerShell 7 startet als pwsh.exe, basiert auf modernem .NET und läuft side-by-side neben 5.1 - es ersetzt 5.1 also nicht. Prüfe die Version in beiden Konsolen:
# Version pruefen (zeigt PSVersion: 5.1 in powershell.exe, 7.x in pwsh.exe)
$PSVersionTable
GUI-Weg: Tippe ins Startmenü PowerShell. Der Eintrag Windows PowerShell ist 5.1; nach der Installation erscheint zusätzlich PowerShell 7. Per Rechtsklick auf Als Administrator ausführen öffnest du eine erhöhte Sitzung (Titelleiste zeigt Administrator).
PowerShell-Weg: Auf Server 2025 mit Desktop Experience nutzt du winget, sonst das MSI. Beachte: winget ist auf Server 2022 (und älter) sowie Server Core nicht verfügbar - dort MSI oder ZIP verwenden.
# PowerShell 7 installieren auf Windows Server 2025 (winget nur mit Desktop Experience)
winget search --id Microsoft.PowerShell --exact
winget install --id Microsoft.PowerShell --source winget # MSIX (ab 7.6 Default)
winget install --id Microsoft.PowerShell --source winget --installer-type wix # klassisches MSI
# PowerShell 7 still via MSI (empfohlen fuer Server/Enterprise, Beispiel mit allen Optionen)
msiexec.exe /package PowerShell-7.6.2-win-x64.msi /quiet ADD_PATH=1 ENABLE_PSREMOTING=1 USE_MU=1 ENABLE_MU=1
PowerShell 7 landet unter $Env:ProgramFiles\PowerShell\7. Die aktuelle stabile Linie ist 7.6.2 (LTS) bzw. 7.5.7. Merke dir: 5.1 und 7 haben getrennte Modulpfade und Profile - ein in 5.1 installiertes Modul ist in 7 nicht automatisch sichtbar.
Schritt 2: Das Cmdlet-Prinzip Verb-Nomen verstehen
Jeder PowerShell-Befehl (Cmdlet) folgt dem Schema Verb-Nomen, etwa Get-Service (lesen), Set-ExecutionPolicy (setzen), New-Item (anlegen) oder Stop-Process (stoppen). Das macht Befehle vorhersehbar: Wenn du das Nomen kennst, errätst du die Aktion über das passende Verb. Cmdlets sind nicht case-sensitive, get-service funktioniert also genauso.
# Zugelassene Verben anzeigen (Microsoft empfiehlt nur diese fuer eigene Funktionen)
Get-Verb
Die freigegebene Verbenliste (Get, Set, New, Remove, Start, Stop, ...) solltest du auch in eigenen Skripten verwenden - das hält deinen Code konsistent und auffindbar.
Schritt 3: Befehle selbst finden mit Get-Command, Get-Help und Get-Member
Du musst nichts auswendig lernen. Drei Discovery-Cmdlets reichen: Get-Command findet Befehle, Get-Help erklärt sie, Get-Member zeigt die Eigenschaften und Methoden eines Objekts.
# Discovery / Hilfe
Get-Command -Verb Get -Noun Service # Befehle finden
Get-Help Get-Service -Examples # Beispiele anzeigen
Get-Help Get-Service -Online # Online-Doku im Browser
Update-Help -Scope AllUsers # Hilfeinhalte laden (als Admin)
Get-Service | Get-Member # Eigenschaften/Methoden eines Objekts
Wichtig: Ohne vorheriges Update-Help liefert Get-Help nur eine knappe Stub-Hilfe. Update-Help -Scope AllUsers braucht Adminrechte und ist bei MSIX-Installationen von PowerShell 7 nicht möglich; in dem Fall nutzt du -Online. Mit Get-Member ermittelst du die echten Eigenschaftsnamen eines Objekts - darauf kommt es im nächsten Schritt an.
Schritt 4: Die Pipeline arbeitet mit Objekten, nicht mit Text
Das ist der zentrale Unterschied zu cmd oder Bash: Die PowerShell-Pipeline reicht echte .NET-Objekte von einem Cmdlet zum nächsten weiter, nicht formatierten Text. Erst die Anzeige am Ende formatiert die Objekte zu lesbaren Spalten. Deshalb filterst und sortierst du nach echten Eigenschaften, nicht nach Textpositionen.
Die wichtigsten Pipeline-Cmdlets sind Where-Object (filtern), Select-Object (Eigenschaften oder die ersten N wählen), Sort-Object (sortieren) und ForEach-Object (pro Objekt eine Aktion). Dazu kommen Measure-Object und Group-Object.
# Pipeline mit Objekten: Dienste filtern, Eigenschaften waehlen, sortieren
Get-Service | Where-Object { $_.Status -eq 'Running' } |
Sort-Object DisplayName |
Select-Object -First 10 Name, DisplayName, Status
# ForEach-Object: pro Objekt eine Aktion
Get-Process | Where-Object CPU -gt 100 | ForEach-Object { "$($_.Name): $($_.CPU)" }
In den Skriptblöcken steht $_ für das aktuell durchlaufende Objekt. Welche Eigenschaften ein Objekt hat, verrät dir wie gesagt Get-Member - verlasse dich nie auf die Spalten der Bildschirmausgabe.
Schritt 5: Variablen, Arrays und Hashtables
Variablen beginnen mit $. Datentypen kannst du erzwingen, indem du den Typ in eckigen Klammern voranstellst. Eine Sammlung legst du als Array an, Schlüssel-Wert-Paare als Hashtable. Achte auf die Anführungszeichen: doppelte interpolieren Variablen, einfache nehmen den Inhalt wörtlich.
# Variablen, Array, Hashtable
[int]$port = 443
$server = 'SRV01'
$liste = @('SRV01','SRV02','SRV03')
$config = @{ Name = $server; Port = $port; Aktiv = $true }
"Server $($config.Name) auf Port $($config.Port)"
Zugriff auf Array-Elemente über den Index ($liste[0] liefert SRV01), auf Hashtable-Werte über Schlüssel ($config['Name'] oder $config.Name). Für Ausdrücke innerhalb von Strings nutzt du die Subexpression $(...), weil "$config.Name" sonst nur $config auflöst und .Name als Text anhängt.
Schritt 6: Execution Policy richtig setzen
Damit eigene .ps1-Skripte laufen, regelt die Execution Policy, was ausgeführt werden darf. Sie ist ein Bequemlichkeits-/Sicherheitsfeature, kein harter Schutz. Der empfohlene Wert ist RemoteSigned: lokal erstellte Skripte laufen, aus dem Internet geladene .ps1 brauchen eine gültige Signatur oder müssen per Unblock-File freigegeben werden. RemoteSigned ist auf Windows-Clients und -Servern bereits der Default.
# Execution Policy anzeigen und (typisch) auf RemoteSigned setzen
Get-ExecutionPolicy -List
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser # ohne Adminrechte
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine # als Admin, alle Nutzer
# Heruntergeladenes Skript entsperren (Mark-of-the-Web entfernen)
Unblock-File -Path .\MeinSkript.ps1
Die Scopes gelten in dieser Präzedenz (höchste zuerst): MachinePolicy, UserPolicy, Process, CurrentUser, LocalMachine. Get-ExecutionPolicy -List zeigt die wahre Lage über alle Scopes. GUI/GPO-Weg: Eine Gruppenrichtlinie unter Computer Configuration\Administrative Templates\Windows Components\Windows PowerShell\Turn on Script Execution überschreibt jede lokale Set-ExecutionPolicy - prüfe das, wenn deine Einstellung nicht greift.
Schritt 7: Dein erstes Skript mit Parametern
Ein Skript ist eine .ps1-Textdatei. Mit dem param()-Block am Anfang machst du es wiederverwendbar und gibst Werte beim Aufruf mit. [Parameter(Mandatory)] erzwingt eine Eingabe, optionale Parameter bekommen einen Standardwert.
# Erstes Skript mit Parametern (Datei z.B. Get-DiskFree.ps1)
param(
[Parameter(Mandatory)][string]$ComputerName,
[int]$MinFreeGB = 10
)
Get-CimInstance -ClassName Win32_LogicalDisk -ComputerName $ComputerName |
Where-Object { ($_.FreeSpace/1GB) -lt $MinFreeGB } |
Select-Object DeviceID, @{N='FreeGB';E={[math]::Round($_.FreeSpace/1GB,1)}}
# Aufruf: .\Get-DiskFree.ps1 -ComputerName SRV01 -MinFreeGB 20
Der Ausdruck @{N='FreeGB';E={...}} ist eine berechnete Eigenschaft (Name/Expression), mit der du eigene Spalten erzeugst. Speichere die Datei, öffne den Ordner in der Konsole und rufe das Skript mit vorangestelltem .\ auf.
Schritt 8: Module nachladen aus der PSGallery
Funktionalität kommt über Module. Viele liefert Microsoft als Rolle/RSAT mit, weitere holst du aus der PSGallery, dem offiziellen Repository. Install-Module installiert systemweit nach $env:ProgramFiles\WindowsPowerShell\Modules (Adminrechte) oder mit -Scope CurrentUser in dein Profil.
# Module / PSGallery
Find-Module -Name PSWindowsUpdate -Repository PSGallery
Install-Module -Name PSWindowsUpdate -Scope CurrentUser # fragt ggf. wegen Untrusted
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted # PSGallery dauerhaft vertrauen
Get-InstalledModule ; Update-Module -Name PSWindowsUpdate
# Modern (PSResourceGet 3.x)
Find-PSResource -Name Az -Repository PSGallery
Install-PSResource -Name Az -Scope CurrentUser -TrustRepository
Die PSGallery ist standardmäßig als Untrusted registriert, deshalb fragt Install-Module nach. Wichtig: Pakete sind community-erstellt und werden von Microsoft nicht geprüft - inspiziere unbekannte Module vorher mit Save-Module. Außerdem braucht der Zugriff TLS 1.2. Der moderne Nachfolger von PowerShellGet 2.x ist Microsoft.PowerShell.PSResourceGet mit Find-PSResource/Install-PSResource.
Schritt 9: Fehlerbehandlung mit try/catch/finally
Robuste Skripte fangen Fehler ab. try/catch/finally fängt allerdings nur terminierende Fehler. Viele Cmdlets erzeugen nicht-terminierende Fehler - die laufen am catch vorbei, solange du nicht -ErrorAction Stop setzt (oder global $ErrorActionPreference='Stop').
# Fehlerbehandlung try/catch/finally (mit -ErrorAction Stop, damit catch greift)
try {
Get-Content 'C:\fehlt.txt' -ErrorAction Stop
}
catch [System.IO.FileNotFoundException] {
Write-Warning "Datei nicht gefunden: $($_.Exception.Message)"
}
catch {
Write-Error "Allgemeiner Fehler: $($_.Exception.Message)"
}
finally {
Write-Host 'Aufraeumen erledigt.'
}
Im catch-Block steht der Fehler in $_ bzw. $Error[0]. Über catch [System.IO.FileNotFoundException] fängst du typspezifisch, ein allgemeines catch am Ende deckt den Rest ab. Der finally-Block läuft immer - ideal zum Aufräumen.
Schritt 10: Admin-Module als Brücke zu den vertiefenden Themen
Die Grundlagen aus den Schritten 1 bis 9 wendest du direkt auf die großen Server-Rollen an. Die Admin-Module installierst du als Windows-Feature/RSAT und lädst sie dann mit Import-Module.
# Admin-Module (Bezug zu weiterfuehrenden Anleitungen)
Install-WindowsFeature -Name RSAT-AD-PowerShell # AD-Cmdlets auf Server
Add-WindowsCapability -Online -Name 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0' # auf Win10/11
Import-Module ActiveDirectory ; Get-ADUser -Filter *
Import-Module Hyper-V ; Get-VM
Import-Module DhcpServer ; Get-DhcpServerv4Scope
AD-Cmdlets (Get-ADUser, New-ADUser), Hyper-V (Get-VM, New-VM, Start-VM) und DHCP (Get-DhcpServerv4Scope, Add-DhcpServerv4Scope) laufen unter PowerShell 5.1 nativ. Unter PowerShell 7 nutzt du bei einigen Windows-spezifischen Modulen die Kompatibilitätsschicht: Import-Module ActiveDirectory -UseWindowsPowerShell. Die konkreten Abläufe findest du in den verlinkten Anleitungen am Ende.
Troubleshooting
- Skript startet nicht / Ausführung verweigert: Prüfe mit
Get-ExecutionPolicy -Listdie effektive Policy. Sind alle ScopesUndefined, gilt auf ClientsRestricted. SetzeSet-ExecutionPolicy RemoteSignedim passenden Scope. - Set-ExecutionPolicy schlägt mit Zugriffsfehler fehl:
-Scope LocalMachinebraucht eine als Administrator gestartete Konsole. Für den eigenen Nutzer reicht-Scope CurrentUserohne Adminrechte. - Meine Policy greift trotzdem nicht: Eine GPO Turn on Script Execution überschreibt jede lokale Einstellung.
Get-ExecutionPolicy -Listzeigt das in den Scopes MachinePolicy/UserPolicy. - catch wird nie ausgeführt: Das Cmdlet erzeugt einen nicht-terminierenden Fehler. Ergänze
-ErrorAction Stopoder setze$ErrorActionPreference='Stop'. - Install-Module schlägt fehl: Die PSGallery ist Untrusted (bestätigen oder
-Force) und braucht TLS 1.2. In älteren Sessions hilft[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12. - Modul aus 5.1 fehlt in PowerShell 7: Beide nutzen getrennte Modulpfade. Installiere das Modul in 7 erneut oder lade es per
Import-Module -UseWindowsPowerShell. - winget nicht gefunden: Auf Server 2022 und Server Core gibt es
wingetnicht. Installiere PowerShell 7 per MSI oder ZIP.
Häufige Fragen
Brauche ich PowerShell 7, oder reicht 5.1?
Für die meisten Admin-Aufgaben auf Windows Server reicht das vorinstallierte 5.1. PowerShell 7 bringt neue Sprachfeatures und ist plattformübergreifend; es läuft parallel und ersetzt 5.1 nicht. Einige Windows-spezifische Module laufen in 7 nur über die Kompatibilitätsschicht.
Warum filtert PowerShell nicht wie grep auf Text?
Weil die Pipeline echte Objekte weiterreicht. Du filterst mit Where-Object nach Eigenschaften wie $_.Status, nicht nach Textspalten. Die echten Eigenschaftsnamen liefert Get-Member.
Welche Execution Policy ist sicher und praktisch?
RemoteSigned. Lokale Skripte laufen, Internet-Skripte brauchen Signatur oder Unblock-File. Setze niemals dauerhaft Bypass oder Unrestricted aus Bequemlichkeit - für Einzelfälle besser pwsh.exe -ExecutionPolicy Bypass -File ... (nur diese Session).
Wieso wird mein catch-Block nie erreicht?
Weil der Fehler nicht-terminierend ist. try/catch fängt nur terminierende Fehler. Setze -ErrorAction Stop am Cmdlet, damit der Fehler terminierend wird und im catch ankommt.
Wie finde ich heraus, welches Cmdlet ich brauche?
Über Get-Command mit Filtern wie -Verb, -Noun oder -Module, dann Get-Help <Cmdlet> -Examples für Beispiele und Get-Member, um die Objekteigenschaften zu sehen.
Fazit
Mit dem Verb-Nomen-Prinzip, der objektbasierten Pipeline und den drei Discovery-Cmdlets Get-Command, Get-Help und Get-Member hast du das Fundament, um Windows Server 2022/2025 produktiv per PowerShell zu administrieren. Setze die Execution Policy auf RemoteSigned, schreibe deine ersten parametrierten .ps1-Skripte, lade Module gezielt nach und sichere kritische Stellen mit try/catch ab. Damit bist du bereit für die spezialisierten Module rund um Active Directory, Hyper-V und DHCP.
Weiterführende Anleitungen und Quellen
Aufbauend auf diesen Grundlagen vertiefen folgende Anleitungen die jeweiligen Admin-Module:
- Active Directory: Domäne einrichten sowie Benutzer und OUs anlegen - nutzt das Modul
ActiveDirectorymitNew-ADUserundGet-ADUser. - Hyper-V: Virtuelle Maschine erstellen und mit Checkpoints arbeiten - nutzt das Modul
Hyper-VmitNew-VMundStart-VM. - DHCP- und DNS-Rolle auf dem Windows Server konfigurieren - nutzt das Modul
DhcpServermitAdd-DhcpServerv4Scope. - Alle Anleitungen der Kategorie Windows Server für weitere Themen rund um die Server-Administration.
Quellen (Microsoft Learn):