CMD vs. PowerShell vs. Bash — entsprechende Befehle
Dieselbe Aufgabe in Eingabeaufforderung, PowerShell und Bash nebeneinander: Dateien, grep, Umgebungsvariablen, Prozesse, Netzwerk, Dienste und Skripting.
Zuletzt geprüft: 2026-10-18, abgeglichen mit der PowerShell-7.6- und Windows-PowerShell-5.1-Referenz auf Microsoft Learn, der Referenz der Windows-Befehle und dem Handbuch zu GNU Bash 5.2.
Dateien & Ordner
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Dateien auflisten # PowerShell-Aliasse: gci, dir und unter Windows ls. | dir | Get-ChildItem | ls -l |
| Alle Dateien rekursiv auflisten # | dir /s /b | Get-ChildItem -Recurse -File | find . -type f |
| Aktuelles Verzeichnis anzeigen # In CMD gibt cd ohne Argument das aktuelle Verzeichnis aus. PowerShell-Alias: pwd, gl; außerdem die Variable $PWD. | cd | Get-Location | pwd |
| Verzeichnis wechseln # CMD braucht /d, um neben dem Ordner auch das Laufwerk zu wechseln. PowerShell-Aliasse: cd, sl, chdir. | cd /d D:\work | Set-Location D:\work | cd /home/me/work |
| Ins Home-Verzeichnis wechseln # | cd %USERPROFILE% | Set-Location ~ | cd ~ |
| Ordner anlegen (inklusive übergeordneter) # mkdir in CMD legt Zwischenordner an, wenn die Befehlserweiterungen aktiviert sind (Standard). In PowerShell ist mkdir eine Funktion, die New-Item -ItemType Directory aufruft. | mkdir a\b\c | New-Item -ItemType Directory -Path a\b\c | mkdir -p a/b/c |
| Leere Datei anlegen # | type nul > file.txt | New-Item file.txt | touch file.txt |
| Datei kopieren # | copy src.txt dst.txt | Copy-Item src.txt dst.txt | cp src.txt dst.txt |
| Ordner rekursiv kopieren # xcopy src dst /E /I funktioniert auch; robocopy ist das unterstützte Tool und kann fortsetzen und wiederholen. | robocopy src dst /E | Copy-Item src dst -Recurse | cp -r src dst |
| Ordner exakt spiegeln Gefährlich # Achtung: Beide löschen Dateien im Ziel, die in der Quelle nicht vorhanden sind. Vertauschst du die beiden Pfade, wird der Ordner geleert, den du behalten wolltest. robocopy /L und rsync -n machen einen Probelauf. | robocopy src dst /MIR | (no cmdlet; call robocopy) | rsync -a --delete src/ dst/ |
| Datei verschieben # | move a.txt archive\ | Move-Item a.txt archive\ | mv a.txt archive/ |
| Datei umbenennen # | ren old.txt new.txt | Rename-Item old.txt new.txt | mv old.txt new.txt |
| Datei löschen # | del file.txt | Remove-Item file.txt | rm file.txt |
| Ordner mit Inhalt löschen Gefährlich # Achtung: Kein Papierkorb und keine Rückfrage bei /q, -Force oder -f. Prüf zuerst den Pfad; in PowerShell zeigt -WhatIf, was entfernt würde. | rmdir /s /q folder | Remove-Item folder -Recurse -Force | rm -rf folder |
| Symbolischen Link erstellen # Unter Windows brauchst du zum Erstellen von Symlinks Administratorrechte, außer der Entwicklermodus ist aktiv. Achte auf die Reihenfolge der Argumente: in CMD/PowerShell zuerst der Link, bei ln zuerst das Ziel. | mklink link.txt target.txt
mklink /D linkdir targetdir | New-Item -ItemType SymbolicLink -Path link.txt -Target target.txt | ln -s target.txt link.txt |
| Dateiberechtigungen ändern # Windows nutzt ACLs statt rwx-Bits; icacls ist meist einfacher als Set-Acl. | icacls file.txt /grant alice:F | Get-Acl / Set-Acl | chmod 644 file.txt |
| Prüfsumme einer Datei (SHA-256) # Get-FileHash nutzt standardmäßig SHA256; für andere -Algorithm MD5 oder SHA1. macOS: shasum -a 256. | certutil -hashfile file.iso SHA256 | Get-FileHash file.iso | sha256sum file.iso |
| ZIP-Datei erstellen # tar.exe (bsdtar) ist ab Windows 10 1803 enthalten; -a wählt das Format anhand der Endung .zip. | tar -a -c -f out.zip folder | Compress-Archive -Path folder -DestinationPath out.zip | zip -r out.zip folder |
| ZIP-Datei entpacken # | tar -xf out.zip | Expand-Archive out.zip -DestinationPath dest | unzip out.zip -d dest |
Dateiinhalte lesen & schreiben
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Datei ausgeben # PowerShell-Aliasse: gc, type und unter Windows cat. | type file.txt | Get-Content file.txt | cat file.txt |
| Datei seitenweise anzeigen # | more file.txt | Get-Content file.txt | Out-Host -Paging | less file.txt |
| Erste 10 Zeilen # -Head ist ein Alias für -TotalCount. | Kein integrierter Befehl | Get-Content file.txt -TotalCount 10 | head -n 10 file.txt |
| Letzte 10 Zeilen # | Kein integrierter Befehl | Get-Content file.txt -Tail 10 | tail -n 10 file.txt |
| Logdatei live verfolgen # | Kein integrierter Befehl | Get-Content app.log -Tail 10 -Wait | tail -f app.log |
| Text in eine Datei schreiben (überschreiben) # In CMD landet ein Leerzeichen vor > mit in der Datei. Windows PowerShell 5.1 schreibt mit > UTF-16 LE, PowerShell 7 UTF-8 ohne BOM. Set-Content -Encoding utf8 ist in beiden eindeutig. | echo hello> file.txt | 'hello' | Set-Content file.txt | echo hello > file.txt |
| Text an eine Datei anhängen # | echo hello>> file.txt | Add-Content file.txt 'hello' | echo hello >> file.txt |
| Zeilen zählen # | find /c /v "" file.txt | (Get-Content file.txt).Count | wc -l file.txt |
| Zwei Dateien vergleichen # In PowerShell unter Windows ist diff ein Alias für Compare-Object, kein Text-Diff. | fc a.txt b.txt | Compare-Object (Get-Content a.txt) (Get-Content b.txt) | diff a.txt b.txt |
| Zeilen sortieren # | sort file.txt | Get-Content file.txt | Sort-Object | sort file.txt |
| Doppelte Zeilen entfernen # | Kein integrierter Befehl | Get-Content file.txt | Sort-Object -Unique | sort -u file.txt |
| Text in einer Datei ersetzen # -replace verwendet reguläre Ausdrücke; die Klammern lesen die ganze Datei ein, bevor Set-Content sie wieder öffnet. sed unter macOS braucht -i ''. | Kein integrierter Befehl | (Get-Content f.txt) -replace 'old','new' | Set-Content f.txt | sed -i 's/old/new/g' f.txt |
Suchen (grep-Entsprechungen)
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Text in Dateien finden # Select-String unterscheidet standardmäßig nicht zwischen Groß- und Kleinschreibung (mit -CaseSensitive änderbar). Für Unterordner: Get-ChildItem -Recurse -Filter *.log | Select-String error. | findstr /s /i /n "error" *.log | Select-String -Path *.log -Pattern error | grep -rin 'error' --include='*.log' . |
| Befehlsausgabe filtern # | ipconfig | findstr IPv4 | ipconfig | Select-String IPv4 | ip a | grep inet |
| Zeilen, die NICHT passen # | findstr /v "DEBUG" app.log | Select-String -Path app.log -Pattern DEBUG -NotMatch | grep -v DEBUG app.log |
| Mit regulärem Ausdruck suchen # findstr unterstützt nur eine kleine Teilmenge regulärer Ausdrücke (kein |, kein {n}). Select-String nutzt reguläre Ausdrücke von .NET. | findstr /r "^ERR.*timeout" app.log | Select-String -Path app.log -Pattern '^ERR.*timeout' | grep -E '^ERR.*timeout' app.log |
| Dateien nach Namen finden # | dir /s /b *.log | Get-ChildItem -Recurse -Filter *.log | find . -name '*.log' |
| Herausfinden, wo ein Programm liegt # In PowerShell ist where ein Alias für Where-Object; tipp where.exe, um das CMD-Tool zu bekommen. | where git | Get-Command git | command -v git |
Umgebungsvariablen
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Alle Variablen auflisten # | set | Get-ChildItem Env: | env |
| Variable lesen # | echo %PATH% | $env:PATH | echo "$PATH" |
| Für diese Sitzung setzen # CMD: keine Leerzeichen um =, sonst werden sie Teil von Name und Wert. | set MY_VAR=hello | $env:MY_VAR = 'hello' | export MY_VAR=hello |
| Dauerhaft setzen (für deinen Benutzer) # setx und SetEnvironmentVariable wirken nur in neuen Fenstern, nicht im aktuellen. setx kürzt Werte mit mehr als 1.024 Zeichen, also bearbeite PATH nicht damit. | setx MY_VAR hello | [Environment]::SetEnvironmentVariable('MY_VAR','hello','User') | echo 'export MY_VAR=hello' >> ~/.bashrc |
| Variable entfernen # | set MY_VAR= | Remove-Item Env:MY_VAR | unset MY_VAR |
| Ordner zu PATH hinzufügen (Sitzung) # PowerShell 7 unter Linux/macOS trennt PATH mit : statt ;. [IO.Path]::PathSeparator liefert das richtige Zeichen. | set PATH=%PATH%;C:\tools | $env:PATH += ';C:\tools' | export PATH="$PATH:/opt/tools" |
| Nur für einen Befehl setzen # | Kein integrierter Befehl | $env:DEBUG = '1'; ./app; Remove-Item Env:DEBUG | DEBUG=1 ./app |
Prozesse
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Prozesse auflisten # | tasklist | Get-Process | ps aux |
| Prozess nach Namen finden # | tasklist /FI "IMAGENAME eq chrome.exe" | Get-Process chrome | pgrep -a chrome |
| Per Prozess-ID beenden # Ohne /F bzw. -Force bittet Windows den Prozess, sich zu schließen. kill sendet SIGTERM; kill -9 erzwingt das Beenden. | taskkill /PID 1234 /F | Stop-Process -Id 1234 -Force | kill 1234 |
| Per Namen beenden # | taskkill /IM notepad.exe /F | Stop-Process -Name notepad | pkill notepad |
| Programm starten # Das leere "" bei start ist der Fenstertitel; ohne es wird ein Programmpfad in Anführungszeichen als Titel interpretiert. | start "" notepad.exe | Start-Process notepad | gedit & |
| Mit erhöhten Rechten ausführen (als Admin/root) # Nimm powershell statt pwsh für Windows PowerShell 5.1. Ab Windows 11 24H2 lässt sich in den Einstellungen auch ein integrierter sudo-Befehl aktivieren. | runas /user:Administrator cmd | Start-Process pwsh -Verb RunAs | sudo command |
| Top 10 der Prozesse nach CPU # CPU in Get-Process ist die gesamte Prozessorzeit in Sekunden seit dem Start, nicht die aktuelle Auslastung in %. | Kein integrierter Befehl | Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 | ps aux --sort=-%cpu | head |
| Was einen Port belegt # Get-NetTCPConnection gibt es nur unter Windows. Die letzte Spalte von netstat -ano ist die PID: Schlag sie mit tasklist /FI "PID eq 1234" nach. | netstat -ano | findstr :8080 | Get-NetTCPConnection -LocalPort 8080 | sudo ss -ltnp | grep :8080 |
Netzwerk
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| IP-Adressen anzeigen # Get-NetIPAddress und die übrigen Net*-Cmdlets gibt es nur unter Windows (Modul NetTCPIP). | ipconfig /all | Get-NetIPAddress | ip addr |
| Host anpingen # ping unter Windows hört standardmäßig nach 4 Pings auf; unter Linux läuft ping bis Ctrl+C. | ping -n 4 example.com | Test-Connection example.com -Count 4 | ping -c 4 example.com |
| TCP-Port testen # Test-NetConnection gibt es nur unter Windows. In PowerShell 7: Test-Connection example.com -TcpPort 443. | Kein integrierter Befehl | Test-NetConnection example.com -Port 443 | nc -zv example.com 443 |
| DNS-Abfrage # Resolve-DnsName gibt es nur unter Windows; nslookup gibt es in allen dreien. | nslookup example.com | Resolve-DnsName example.com | dig example.com |
| Route verfolgen # | tracert example.com | Test-NetConnection example.com -TraceRoute | traceroute example.com |
| DNS-Cache leeren # Die Bash-Zeile gilt für Systeme mit systemd-resolved. | ipconfig /flushdns | Clear-DnsClientCache | sudo resolvectl flush-caches |
| HTTP-GET (API-Aufruf) # Invoke-RestMethod wandelt JSON in Objekte um; Invoke-WebRequest liefert Status, Header und Rohinhalt. | curl.exe https://api.example.com/items | Invoke-RestMethod https://api.example.com/items | curl https://api.example.com/items |
| Datei herunterladen # curl.exe ist ab Windows 10 1803 enthalten. Unter Windows PowerShell 5.1 ergänzt du Invoke-WebRequest auf Rechnern ohne eingerichteten Internet Explorer um -UseBasicParsing. | curl.exe -L -o file.zip https://example.com/file.zip | Invoke-WebRequest https://example.com/file.zip -OutFile file.zip | curl -LO https://example.com/file.zip |
| JSON per POST senden # CMD kennt keine einfachen Anführungszeichen, daher werden innere doppelte Anführungszeichen für curl.exe mit Backslashes escapt. | curl.exe -X POST -H "Content-Type: application/json" -d "{\"a\":1}" https://api.example.com | Invoke-RestMethod https://api.example.com -Method Post -ContentType 'application/json' -Body (@{a=1} | ConvertTo-Json) | curl -X POST -H 'Content-Type: application/json' -d '{"a":1}' https://api.example.com |
| Per SSH mit einem Server verbinden # Der OpenSSH-Client ist unter Windows 10 ab 1809 und Windows 11 standardmäßig installiert. | ssh user@host | ssh user@host | ssh user@host |
Dienste & System
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Dienste auflisten # In Windows PowerShell 5.1 ist sc ein Alias für Set-Content: Tipp dort sc.exe. Ab PowerShell 6 ist dieser Alias entfernt. | sc query | Get-Service | systemctl list-units --type=service |
| Dienststatus # | sc query Spooler | Get-Service Spooler | systemctl status nginx |
| Dienst starten / stoppen # | net start Spooler
net stop Spooler | Start-Service Spooler
Stop-Service Spooler | sudo systemctl start nginx
sudo systemctl stop nginx |
| Dienst neu starten # | net stop Spooler && net start Spooler | Restart-Service Spooler | sudo systemctl restart nginx |
| Beim Hochfahren starten # sc.exe braucht das Leerzeichen nach start= und keines davor. | sc config Spooler start= auto | Set-Service Spooler -StartupType Automatic | sudo systemctl enable nginx |
| Infos zu Betriebssystem und Hardware # | systeminfo | Get-ComputerInfo | uname -a; cat /etc/os-release |
| Computername # | hostname | $env:COMPUTERNAME | hostname |
| Aktueller Benutzer # In PowerShell unter Windows auch $env:USERNAME. | whoami | whoami | whoami |
| Freier Speicherplatz # Ältere Windows-Versionen verlangen für fsutil Administratorrechte. Get-Volume (nur Windows) zeigt ebenfalls Größe und freien Speicher. | fsutil volume diskfree C: | Get-PSDrive -PSProvider FileSystem | df -h |
| Laufzeit seit dem Start # Get-Uptime gibt es ab PowerShell 6. In 5.1: (Get-Date) - (Get-CimInstance Win32_OperatingSystem).LastBootUpTime. | systeminfo | find "Boot Time" | Get-Uptime | uptime |
| Sofort neu starten # | shutdown /r /t 0 | Restart-Computer | sudo reboot |
| Bildschirm leeren # cls und clear funktionieren beide in PowerShell unter Windows. | cls | Clear-Host | clear |
| Befehlsverlauf # Get-History umfasst nur diese Sitzung. PSReadLine speichert älteren Verlauf in der Datei unter (Get-PSReadLineOption).HistorySavePath; Ctrl+R durchsucht ihn in allen drei Shells. | doskey /history | Get-History | history |
| Hilfe zu einem Befehl # Führ einmal Update-Help aus (in 5.1 mit Administratorrechten), um die vollständige PowerShell-Hilfe herunterzuladen. | dir /? | Get-Help Get-ChildItem -Examples | man ls |
| Aktuelles Datum # %date% folgt dem Regionalformat des Rechners, daher scheitern Skripte, die es auswerten, bei anderen Ländereinstellungen. | echo %date% | Get-Date -Format 'yyyy-MM-dd' | date +%F |
| 5 Sekunden warten # | timeout /t 5 | Start-Sleep -Seconds 5 | sleep 5 |
| Ausgabe in die Zwischenablage kopieren # macOS: pbcopy. Wayland: wl-copy. Get-Clipboard liest sie in PowerShell wieder aus. | dir | clip | Get-ChildItem -Name | Set-Clipboard | ls | xclip -selection clipboard |
Objekte vs. Text weiterleiten
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Spalten / Eigenschaften auswählen # PowerShell leitet .NET-Objekte weiter, daher wählst du Eigenschaften nach Namen aus, statt Spalten zu parsen. | Kein integrierter Befehl | Get-Process | Select-Object Name, Id, WS | ps -eo comm,pid,rss |
| Zeilen nach einem Wert filtern # PowerShell versteht Literale wie 500MB oder 1GB. awk vergleicht Spalte 6 (RSS in KB). | tasklist | findstr chrome | Get-Process | Where-Object WS -gt 500MB | ps aux | awk '$6 > 500000' |
| Etwas für jedes Element tun # $_ (oder $PSItem) ist das aktuelle Objekt. In einer .bat-Datei schreibst du %%f statt %f. | for %f in (*.txt) do echo %f | Get-ChildItem *.txt | ForEach-Object { $_.Name } | for f in *.txt; do echo "$f"; done |
| Eigenschaften eines Objekts ansehen # Der nützlichste Befehl, um PowerShell zu erkunden; probier auch | Format-List *. | Kein integrierter Befehl | Get-Process | Get-Member | Kein integrierter Befehl |
| JSON parsen # Nutze -Raw, damit die Datei als ein String ankommt; für die Ausgabe ConvertTo-Json -Depth 10 (die Standardtiefe ist 2). | Kein integrierter Befehl | Get-Content data.json -Raw | ConvertFrom-Json | jq . data.json |
| CSV lesen und filtern # Werte aus Import-Csv sind Strings; für Zahlenvergleiche mit [int] umwandeln. | Kein integrierter Befehl | Import-Csv users.csv | Where-Object { [int]$_.Age -gt 30 } | awk -F, 'NR>1 && $3 > 30' users.csv |
| Als CSV exportieren # -NoTypeInformation ist ab PowerShell 6 Standard, in 5.1 aber nötig. | Kein integrierter Befehl | Get-Process | Export-Csv procs.csv -NoTypeInformation | ps -eo pid,comm --no-headers | awk '{print $1","$2}' > procs.csv |
| Anzahl, Summe, Durchschnitt # | find /c /v "" file.txt | Get-ChildItem -File | Measure-Object Length -Sum -Average | ls -l | awk '{s+=$5} END {print s}' |
Skripting: Variablen, Bedingungen, Schleifen, Funktionen
| Aufgabe | CMD (Eingabeaufforderung) | PowerShell | Bash (Linux/macOS) |
|---|---|---|---|
| Variable setzen # bash: keine Leerzeichen um = (name = Ada führt einen Befehl namens name aus). | set name=Ada | $name = 'Ada' | name=Ada |
| Variable in einem String verwenden # | echo Hello %name% | "Hello $name" | echo "Hello $name" |
| Rechnen # CMD und bash rechnen nur mit Ganzzahlen; PowerShell nutzt .NET-Zahlen. | set /a n=5*3 | $n = 5 * 3 | n=$((5 * 3)) |
| Benutzereingabe lesen # | set /p name=Name: | $name = Read-Host 'Name' | read -rp 'Name: ' name |
| Skriptargumente # In .bat-Dateien entfernt %~1 umschließende Anführungszeichen. Ein param()-Block gibt PowerShell-Skripten benannte, typisierte Parameter. | %1 %2 … %* | $args[0] or param($Path) | $1 $2 … "$@" |
| If / else mit einem String # Vergleichsoperatoren in PowerShell sind Wörter: -eq -ne -gt -lt -like -match. = und > stehen für Zuweisung und Umleitung. | if "%a%"=="yes" (echo on) else (echo off) | if ($a -eq 'yes') { 'on' } else { 'off' } | if [ "$a" = "yes" ]; then echo on; else echo off; fi |
| Zahlen vergleichen # CMD: EQU NEQ LSS LEQ GTR GEQ. | if %n% GTR 5 echo big | if ($n -gt 5) { 'big' } | if (( n > 5 )); then echo big; fi |
| Wenn eine Datei existiert # | if exist file.txt echo yes | if (Test-Path file.txt) { 'yes' } | if [ -f file.txt ]; then echo yes; fi |
| Exit-Code des letzten Programms # In PowerShell ist $? $true/$false für den letzten Befehl; $LASTEXITCODE ist der numerische Code des letzten nativen Programms. | echo %ERRORLEVEL% | $LASTEXITCODE | echo $? |
| Nächsten Befehl nur bei Erfolg / Fehler ausführen # Die Pipeline-Verkettungsoperatoren && und || kamen mit PowerShell 7.0; Windows PowerShell 5.1 lehnt sie ab. | build && deploy
build || echo failed | build && deploy (PowerShell 7+)
build; if ($?) { deploy } (5.1) | build && deploy
build || echo failed |
| Schleife über eine Liste # | for %i in (a b c) do echo %i | foreach ($x in 'a','b','c') { $x } | for x in a b c; do echo "$x"; done |
| Schleife von 1 bis 5 # | for /l %i in (1,1,5) do echo %i | foreach ($i in 1..5) { $i } | for i in {1..5}; do echo "$i"; done |
| Schleife über die Zeilen einer Datei # | for /f "usebackq delims=" %l in ("file.txt") do echo %l | foreach ($line in Get-Content file.txt) { $line } | while IFS= read -r line; do echo "$line"; done < file.txt |
| While-Schleife # CMD kennt kein while; nutze in einer .bat-Datei goto mit einem Label. | :loop
set /a i+=1
if %i% lss 5 goto loop | while ($i -lt 5) { $i++ } | while [ "$i" -lt 5 ]; do i=$((i+1)); done |
| Funktion definieren und aufrufen # PowerShell-Funktionen rufst du wie Befehle auf: Greet Ada, nicht Greet("Ada"). | call :greet Ada
goto :eof
:greet
echo Hello %~1
exit /b | function Greet($Name) { "Hello $Name" }
Greet Ada | greet() { echo "Hello $1"; }
greet Ada |
| Befehlsausgabe in einer Variablen speichern # | for /f "delims=" %i in ('hostname') do set h=%i | $h = hostname | h=$(hostname) |
| Ausgabe verwerfen # | command >nul 2>&1 | command *> $null | command >/dev/null 2>&1 |
| Kommentar # | rem comment
:: comment | # comment
<# block #> | # comment |
| Skriptdatei und wie man sie ausführt # PowerShell führt Skripte aus dem aktuellen Ordner nicht ohne .\ aus und blockiert sie unter Umständen komplett: siehe Ausführungsrichtlinie unten. | script.bat | .\script.ps1 | chmod +x script.sh && ./script.sh |
Alias-Fallen in PowerShell: ls, curl, wget, sc, where
PowerShell bringt Aliasse mit, die wie Unix- oder CMD-Befehle aussehen, aber Cmdlets mit anderen Parametern ausführen. Welche es gibt, hängt von der Edition und dem Betriebssystem ab. Get-Alias name zeigt, worauf ein Name in deiner Sitzung verweist.
| Du tippst | Windows PowerShell 5.1 | PowerShell 7 unter Windows | PowerShell 7 unter Linux/macOS |
|---|---|---|---|
curlTipp in 5.1 curl.exe, um das echte curl zu bekommen. Seine Flags (-X, -H, -d) bedeuten Invoke-WebRequest nichts. | Invoke-WebRequest | kein Alias: startet curl.exe | natives curl |
wgetNutze Invoke-WebRequest url -OutFile name oder curl.exe -LO url. | Invoke-WebRequest | kein Alias (unter Windows standardmäßig kein wget) | natives wget, falls installiert |
ls, dirFlags wie ls -la scheitern unter Windows: Nimm Get-ChildItem -Force. | Get-ChildItem | Get-ChildItem | ls = natives ls; dir = Get-ChildItem |
cat, type | Get-Content | Get-Content | cat = natives cat; type = Get-Content |
cp, mv, rm, rmdirrm -rf ist kein gültiges PowerShell: Nimm Remove-Item -Recurse -Force. | Copy-Item, Move-Item, Remove-Item | dieselben Cmdlets | native Befehle |
ps, kill | Get-Process, Stop-Process | dieselben Cmdlets | native Befehle |
sort, tee, diffdiff a b vergleicht in PowerShell unter Windows Objekte, nicht die Zeilen zweier Dateien. | Sort-Object, Tee-Object, Compare-Object | dieselben Cmdlets | native Befehle |
scIn 5.1 schreibt sc query eine Datei namens query. Nimm sc.exe. | Set-Content | kein Alias: startet sc.exe | entfällt |
whereNimm where.exe oder Get-Command, um ein Programm zu finden. | Where-Object | Where-Object | Where-Object |
echoecho -n unterdrückt den Zeilenumbruch nicht; nimm Write-Host -NoNewline. | Write-Output | Write-Output | Write-Output |
man | help | help | natives man |
Anführungszeichen & Escaping
Die meisten Fehler nach dem Muster „läuft in der einen Shell, scheitert in der anderen“ liegen an Anführungszeichen. Das Escape-Zeichen ist in jeder Shell ein anderes.
| Was | CMD | PowerShell | Bash |
|---|---|---|---|
| Literaler String (ohne Ersetzung) | Keine literalen Anführungszeichen: %VAR% wird auch innerhalb von "…" ersetzt | 'Cost: $5' | 'Cost: $5' |
| String mit Variablen | "Hello %name%" | "Hello $name, it is $(Get-Date -Format t)" | "Hello $name, it is $(date +%R)" |
| Escape-Zeichen | ^ (z. B. ^& ^| ^>) | ` Backtick (z. B. `n Zeilenumbruch, `t Tab, `$ literales $) | \ Backslash |
| Anführungszeichen innerhalb eines Strings in Anführungszeichen | "" innerhalb von "…" bei vielen Programmen; je nach Programm verschieden | 'It''s' oder "Say `"hi`"" | 'It'\''s' oder "Say \"hi\"" |
| Zeilenfortsetzung | ^ am Zeilenende | ` am Zeilenende (oder Zeile mit | beenden) | \ am Zeilenende |
| Literales % oder $ in einem Skript | %% in einer .bat-Datei | '$' in einfachen Anführungszeichen oder `$ | '$' in einfachen Anführungszeichen oder \$ |
| Argumente unverändert an ein natives Programm übergeben | (nicht nötig) | --% verhindert, dass PowerShell den Rest der Zeile parst | (nicht nötig) |
Die Übergabe von Anführungszeichen an native Programme (curl.exe, git, node) hat sich in PowerShell 7.3 geändert: Argumente mit eingebetteten doppelten Anführungszeichen werden jetzt so übergeben, wie sie geschrieben sind, gesteuert über $PSNativeCommandArgumentPassing. In Windows PowerShell 5.1 müssen die inneren Anführungszeichen desselben JSON-Bodys oft doppelt escapt werden – deshalb steigen viele auf Invoke-RestMethod mit ConvertTo-Json um.
Ausführungsrichtlinie: „Die Ausführung von Skripts ist auf diesem System deaktiviert“
PowerShell verweigert die Ausführung von .ps1-Dateien, wenn die Ausführungsrichtlinie Restricted ist – faktisch der Standard für Windows PowerShell auf Windows-Client-Editionen (Windows 10 und 11). Windows Server verwendet standardmäßig RemoteSigned: Lokale Skripte laufen, heruntergeladene müssen signiert oder entsperrt sein. Unter Linux und macOS ist die Richtlinie Unrestricted und lässt sich nicht ändern.
Get-ExecutionPolicy -Listzeigt die Richtlinie für jeden Bereich; der spezifischste definierte Bereich gewinnt (Gruppenrichtlinien haben Vorrang vor allem).Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserlässt deine eigenen Skripte ohne Administratorrechte laufen.Unblock-File .\script.ps1entfernt die Markierung „aus dem Internet heruntergeladen“ von einem Skript, dem du vertraust.pwsh -ExecutionPolicy Bypass -File script.ps1(oderpowershellfür 5.1) wendet eine Richtlinie nur auf eine Sitzung an.
Die Ausführungsrichtlinie ist eine Sicherung gegen das versehentliche Ausführen von Skripten, keine Sicherheitsgrenze: Jeder kann den Inhalt des Skripts in die Konsole einfügen.
Windows PowerShell 5.1 vs. PowerShell 7
- Zwei Programme:
powershell.exeist Windows PowerShell 5.1, in Windows integriert und ohne neue Funktionen.pwshist PowerShell 7, separat installiert und plattformübergreifend; beide können parallel installiert sein. - In 7.0 neu hinzugekommene Operatoren:
&&und||zwischen Befehlen, der ternäre Operator$a ? 'yes' : 'no'sowie Null-Koaleszenz mit??/??=. - Dateikodierung:
>undOut-Fileschreiben in 5.1 UTF-16 LE, undSet-Contentverwendet die ANSI-Codepage. PowerShell 7 schreibt überall UTF-8 ohne BOM – genau das, was Git, Linux-Tools und die meisten Editoren erwarten. - Aliasse: 7 hat unter Windows
curl,wgetundscgestrichen und überlässt unter Linux/macOSls,cp,rm,cat,psund weitere den nativen Befehlen (siehe Tabelle oben). - Fehlende Module: Reine Windows-Cmdlets wie
Get-NetIPAddress,Test-NetConnectionundResolve-DnsNamefunktionieren in PowerShell 7 unter Windows, gibt es aber unter Linux und macOS nicht.
Bash unter Windows ausführen: WSL
Das Windows-Subsystem für Linux führt eine echte Linux-Distribution neben Windows aus, sodass jeder Bash-Befehl in der rechten Spalte genau so funktioniert. wsl --install in einer Eingabeaufforderung mit Administratorrechten installiert es standardmäßig mit Ubuntu (Windows 10 ab Version 2004 sowie Windows 11); wsl -l -v listet die installierten Distributionen auf.
- Einen einzelnen Linux-Befehl aus CMD oder PowerShell ausführen:
wsl ls -la, oder per Pipe kombinieren:dir | wsl grep txt. - Windows-Laufwerke erscheinen unter Linux in
/mnt/c; Linux-Dateien erreichst du im Explorer unter\\wsl.localhost\Ubuntu(ältere Builds:\\wsl$\Ubuntu). - Leg Projekte im Linux-Dateisystem (~/) ab, nicht unter /mnt/c: Dateizugriffe über diese Grenze hinweg sind deutlich langsamer.
Mehr zur Linux-Seite findest du im Spickzettel für Linux-Befehle.
Ein Problem gefunden oder etwas, das besser sein könnte? Wir lesen jede Nachricht und beheben Fehler schnell.
Diese Tabelle CMD vs. PowerShell vs. Bash zeigt dieselbe Aufgabe in der Windows-Eingabeaufforderung, in PowerShell und in Bash in einer Zeile: Dateien auflisten und kopieren, Text in Dateien finden (die PowerShell-Entsprechung von grep ist Select-String), Umgebungsvariablen, Prozesse, Netzwerk, Dienste, Dateiinhalte lesen und schreiben sowie Skripting mit Variablen, Bedingungen, Schleifen und Funktionen. Suche nach einem Befehl aus einer der drei Shells, und du bekommst seine Gegenstücke, jeweils mit Kopier-Button.
Der Spickzettel behandelt auch, was beim Wechsel zwischen den Shells meist schiefgeht: PowerShell-Aliasse, die wie Unix-Befehle aussehen, aber keine sind (curl und wget in Windows PowerShell 5.1, ls und rm überall unter Windows), unterschiedliche Quoting- und Escape-Zeichen, der Fehler der Ausführungsrichtlinie, der .ps1-Skripte blockiert, und die Unterschiede zwischen Windows PowerShell 5.1 und PowerShell 7. PowerShell-Befehle funktionieren in beiden Versionen, sofern kein Hinweis etwas anderes sagt; wo es keine CMD-Entsprechung gibt, sagt die Tabelle das, statt eine zu erfinden.
So funktioniert’s
- Suche nach dem Befehl, den du kennst, in einer beliebigen Shell (zum Beispiel „grep“, „findstr“ oder „Select-String“), oder nach der Aufgabe („Prozess beenden“, „Umgebungsvariable“).
- Lies in der Zeile die Entsprechung in den anderen beiden Shells ab und klicke neben der, die du brauchst, auf „Kopieren“.
- Beachte den Hinweis unter dem Namen der Aufgabe: Er weist auf Versionsunterschiede (PowerShell 5.1 vs. 7) und Cmdlets nur für Windows hin.
- Scrolle zu den Abschnitten über Aliasse, Quoting und Ausführungsrichtlinie, wenn sich ein Befehl anders verhält als erwartet.
- Nutze „Drucken / Als PDF speichern“ für ein Exemplar auf dem Schreibtisch; die Seite funktioniert auch auf dem Smartphone, wo jede Zeile zu einer Karte wird.
Häufige Fragen
Was ist die PowerShell-Entsprechung von grep?
Select-String. Durchsuche eine Datei mit Select-String -Path app.log -Pattern error oder filtere die Ausgabe eines Befehls mit ipconfig | Select-String IPv4. Standardmäßig wird Groß-/Kleinschreibung ignoriert (füge -CaseSensitive hinzu), es verwendet reguläre Ausdrücke von .NET, und -NotMatch entspricht grep -v. Für rekursive Suchen leite Get-ChildItem -Recurse -Filter *.log in Select-String weiter. Der kurze Alias ist sls.
Warum verhält sich curl in PowerShell seltsam?
In Windows PowerShell 5.1 sind curl und wget Aliasse für Invoke-WebRequest, daher werden curl-Flags wie -X, -H und -d abgelehnt oder bedeuten etwas anderes. Tippe curl.exe, um das echte curl auszuführen, das ab Windows 10 1803 mitgeliefert wird. PowerShell 7 hat diese Aliasse entfernt, dort startet curl also curl.exe. Unter Linux und macOS war curl nie ein Alias.
Ist PowerShell besser als CMD?
Für alles, was über das Starten eines Programms oder eine kurze Batchdatei hinausgeht, ja. PowerShell leitet strukturierte Objekte statt Text weiter, du filterst und sortierst also nach Eigenschaftsnamen (Where-Object, Sort-Object), statt Spalten zu parsen, und es hat echte Funktionen, Fehlerbehandlung, Unterstützung für JSON und CSV sowie Remoting. CMD ist weiterhin in Ordnung für alte .bat-Dateien und manche Installer, und jedes CMD-Tool (ipconfig, robocopy, netstat) lässt sich auch aus PowerShell heraus ausführen.
Wie behebe ich „Die Ausführung von Skripts ist auf diesem System deaktiviert“?
Das ist die Ausführungsrichtlinie, die auf den Client-Editionen von Windows 10 und 11 standardmäßig auf Restricted steht. Führe in PowerShell Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser aus (keine Administratorrechte nötig). Danach laufen deine eigenen Skripte, und aus dem Internet heruntergeladene Skripte müssen signiert sein oder mit Unblock-File freigegeben werden. Get-ExecutionPolicy -List zeigt, was wo gesetzt ist; eine Gruppenrichtlinie hat Vorrang vor allem, was du selbst einstellst.
Kann ich Bash-Befehle unter Windows ausführen?
Ja, mit dem Windows-Subsystem für Linux. Führe wsl --install in einer Eingabeaufforderung mit erhöhten Rechten aus (Windows 10 ab Version 2004 oder Windows 11), um Ubuntu zu installieren, und öffne es dann über das Startmenü – oder führe einzelne Befehle aus CMD oder PowerShell mit wsl gefolgt vom Befehl aus, etwa wsl grep -rn TODO. Git for Windows enthält außerdem Git Bash, eine schlankere Bash mit den gängigen Unix-Tools.
Was ist der Unterschied zwischen Windows PowerShell und PowerShell 7?
Windows PowerShell 5.1 (powershell.exe) ist in Windows integriert und bekommt nur noch Fehlerkorrekturen. PowerShell 7 (pwsh) ist die aktuelle, plattformübergreifende Version, die unter Windows, Linux und macOS läuft und separat installiert wird; beide können parallel installiert sein. Version 7 bringt && und || zwischen Befehlen, den ternären Operator und ??, schreibt Dateien standardmäßig in UTF-8 und verzichtet auf einige verwirrende Aliasse wie curl und wget.
Objekte statt Text: die eine Idee, mit der PowerShell Klick macht
In CMD und Bash transportiert eine Pipe Text. Um in Bash den Prozess mit dem höchsten Speicherverbrauch zu finden, pickst du mit sort -k oder awk die richtige Spalte aus der Ausgabe von ps, und der Befehl bricht, wenn sich das Spaltenlayout ändert. In PowerShell transportiert die Pipe Objekte mit benannten Eigenschaften, dieselbe Aufgabe lautet also Get-Process | Sort-Object WS -Descending | Select-Object -First 1. Nichts wird geparst, und die Eigenschaftsnamen sind auf jedem Rechner gleich.
Praktisch führt das zu einer anderen Arbeitsweise beim Erkunden. In Bash liest du eine Manpage, um das Ausgabeformat zu lernen; in PowerShell leitest du einen beliebigen Befehl an Get-Member weiter, um zu sehen, welche Eigenschaften und Methoden seine Objekte haben, filterst dann mit Where-Object und wählst Felder mit Select-Object aus. Erst wenn die Ausgabe den Bildschirm oder eine Datei erreicht, macht PowerShell Text daraus.
Native Programme wie ipconfig, git oder curl.exe geben auch in PowerShell Text aus, daher funktionieren Select-String und -match bei ihnen so, wie grep es würde. Ihr Exit-Code steht in $LASTEXITCODE, nicht in $?.
Ein Skript zwischen den drei Shells übersetzen
Eine Übersetzung Zeile für Zeile funktioniert bei einfachen Skripten, aber ein paar Unterschiede erwischen fast jeden:
• Vergleichsoperatoren: CMD verwendet == für Strings und EQU, GTR, LSS für Zahlen; PowerShell verwendet -eq, -gt, -lt, -like und -match (ein einfaches > ist eine Umleitung); Bash verwendet = innerhalb von [ ] für Strings und -gt oder (( )) für Zahlen.
• Variablen: %name% in CMD (und !name! in Schleifen nach setlocal EnableDelayedExpansion), $name in PowerShell, $name in Bash ohne Leerzeichen um = bei der Zuweisung.
• Schleifen in .bat-Dateien verdoppeln das Prozentzeichen: for %%f in (*.txt) in einer Datei, for %f an der Eingabeaufforderung.
• Pfade: PowerShell akzeptiert unter Windows sowohl / als auch \; Bash unter Linux braucht /. Umgebungsvariablen unterscheiden unter Windows nicht zwischen Groß- und Kleinschreibung, unter Linux schon.
• Fehler: CMD macht nach einem Fehler weiter, wenn du %ERRORLEVEL% nicht prüfst; Bash macht weiter, wenn nicht set -e gesetzt ist; PowerShell macht nach nicht abbrechenden Fehlern weiter, wenn nicht $ErrorActionPreference = 'Stop' gesetzt ist.
Wenn ein Skript unter Windows und Linux laufen muss, ersparen dir PowerShell 7 oder Bash unter WSL zwei getrennte Fassungen.
Ähnliche kostenlose Tools
- Linux-Befehle-Spickzettel — Linux-Befehle nach Aufgabe, von Dateien und Rechten bis zu Netzwerk, systemd und Textverarbeitung. Jeder Eintrag mit Optionen, kopierbaren Beispielen und macOS-Hinweisen.
- Windows-Tastenkombinationen — Alle Windows-11-Tastenkombinationen in einer durchsuchbaren, druckbaren Liste: Windows-Taste, Snap, Desktops, Screenshots, Datei-Explorer.
- Mac-Tastenkombinationen — Alle macOS-Kurzbefehle mit erklärten Symbolen ⌘ ⌥ ⌃ ⇧: Bildschirmfotos, Fensteranordnung, Finder, Safari und Sonderzeichen.
- curl in Code — Füge einen curl-Befehl ein, auch aus „Als cURL kopieren“ in Chrome, und erhalte dieselbe Anfrage in Python, JavaScript, Node, Go, PHP, Ruby, Java, C#, wget oder HTTPie.
- Git-Spickzettel — Git-Befehle geordnet nach dem, was du tun willst: letzten Commit rückgängig machen, Branch umbenennen, Remote-Branch löschen. Modernes switch/restore mit klassischen Entsprechungen und Warnhinweisen.