- 1 Section
- 10 Lessons
- unbegrenzt
- CMD – Windows-Kommandozeile10
- 1.1CMD vs. PowerShell vs. WSL
- 1.2Navigation: cd, dir, md, rd, tree
- 1.3Dateioperationen: copy, move, del, ren, type
- 1.4Netzwerkbefehle: ipconfig, ping, tracert, nslookup
- 1.5Systeminformationen: systeminfo, tasklist, taskkill
- 1.6Batch-Scripting: Grundstruktur und Variablen
- 1.7Batch: Schleifen und Bedingungen
- 1.8Erweiterte Netzwerkdiagnose: arp, route, netsh
- 1.9Benutzer und Rechte: net user, net localgroup
- 1.10Praxisszenarien: Troubleshooting mit CMD
Batch: Schleifen und Bedingungen
Mit den Variablen und Argumenten aus L6 kannst du Daten ablegen – aber noch keine Logik. Bedingungen (if) treffen Entscheidungen, Schleifen (for) wiederholen Aufgaben. Das sind die zwei Konstrukte die deine Skripte erst wirklich nützlich machen.
Faire Warnung: Batch hat hier besonders eigenwillige Syntax. Anders als in Bash, PowerShell oder modernen Programmiersprachen. Die for-Variationen sind ein Universum für sich, und die berüchtigte Delayed Expansion bringt erfahrene Entwickler ins Schwitzen. Aber das alles lässt sich beherrschen – Schritt für Schritt.
1) if – die einfache Bedingung
Die Basis-Form ist if BEDINGUNG (BLOCK) else (BLOCK). Die Klammern sind wichtig:
Was hier wichtig ist:
- Die öffnende Klammer muss in der gleichen Zeile wie das
ifstehen (oder direkt danach mit Leerzeichen) - Das
) else (muss exakt so geschrieben sein – mit Leerzeichen drum herum - Bei Zahl-Vergleichen: nicht
==sondern Operatoren wieGEQ
Der letzte Punkt ist eine der größten Anfänger-Stolperfallen. Zwei Vergleichs-Arten existieren parallel:
if %a% == 10 vergleicht als String! Wenn %a% = „10 " (mit Space) oder „010", ist es nicht gleich „10". Für Zahlen IMMER EQU und Co. nehmen. Andererseits: für String-Vergleiche IMMER == (oder EQU würde scheitern wenn der String keine Zahl ist).if %var% == "test" ... – wenn %var% leer ist, wird daraus if == "test", ein Syntax-Fehler. Lösung: if "%var%" == "test" mit Quotes drum. Damit wird leere Variable zu "" und kein Fehler. Faustregel: bei String-Vergleichen immer beide Seiten in Quotes.2) Spezielle if-Formen
Es gibt einige nützliche Spezial-Bedingungen:
Die if errorlevel N-Falle ist legendär: sie ist wahr wenn der Errorlevel N oder größer ist. Daher prüfst du am besten von oben runter, oder nutzt %errorlevel% direkt mit EQU. Wer das durcheinanderbringt, debuggt stundenlang.
3) if-Builder zum Ausprobieren
Bau dir interaktiv eine if-Bedingung zusammen und sieh sofort das Ergebnis:
"hallo" mit EQU gegen "hallo" – funktioniert das? Ja, EQU vergleicht auch Strings (case-sensitive!). Aber bei Zahl-Vergleich mit Strings („10" vs „abc"): Fehler. Mit Quotes drum geht's als String-Vergleich.4) goto und Labels: Verzweigungen
Batch hat keine eingebauten Funktionen wie PowerShell oder Bash. Stattdessen gibt es das altertümliche goto und Labels. Ein Label ist :NAME in eigener Zeile, gesprungen wird mit goto NAME:
Mit call :NAME kann ein Label sogar wie ein Unter-Programm funktionieren – mit exit /b kehrt es zurück:
Das ist Batch-„Funktionen" – primitiv aber funktional. Wer ernsthafte Logik braucht, sollte überlegen ob Batch wirklich das richtige Werkzeug ist. PowerShell-Funktionen sind 100-mal komfortabler.
5) for – die Schleifen-Übersicht
for in Batch hat fünf Varianten – jede für einen anderen Zweck. Klick durch die Tabs:
%%i (in Batch-Skripten – doppeltes %!) oder %i (in der direkten CMD). Diese Variable nimmt nacheinander verschiedene Werte an. Was sie annimmt, hängt vom Typ ab. %%i versus %i ist eine der nervigsten Falle: Batch-Skript braucht doppeltes, interaktive CMD einfaches.6) Die berühmt-berüchtigte for /F
for /F ist der mächtigste – und kryptischste – Batch-Befehl. Damit liest du Dateien, parst CSV, verarbeitest Command-Output. Die Syntax sieht ein bisschen so aus:
Die Options sind das Spannende:
| Option | Bedeutung |
|---|---|
tokens=N | Welche Spalte(n) gelesen werden. tokens=1,3 = 1. und 3. Spalte |
tokens=1,* | 1. Spalte einzeln, Rest als zusammenhängender String |
delims=X | Trenner (Default: Leerzeichen+Tab). delims=, für CSV |
skip=N | Erste N Zeilen überspringen (z.B. CSV-Header) |
eol=X | Zeichen das Zeilen als Kommentar markiert |
usebackq | Andere Quoting-Regeln (Quelle in Backticks; Dateien in Quotes) |
Die Quelle kann sein: ein Dateiname, eine Liste von Strings in Backticks `...` (Erzeugung aus Befehl), oder direkt Strings.
Verstanden? Falls nicht: macht nichts. for /F ist eine der schwersten Sachen in Batch. Wenn du komplexes Parsing brauchst: nimm PowerShell mit Import-Csv. Das ist 10-mal lesbarer.
7) Delayed Expansion: das große Mysterium
Wenn du in einem Code-Block (innerhalb von if oder for) eine Variable änderst und im gleichen Block wieder lesen willst – stolperst du. Schau dir das an:
Was ist passiert? Batch ersetzt Variablen zur Parse-Zeit – also bevor der Block ausgeführt wird. Das %zaehler% wird durch den Wert beim Lesen des Skripts ersetzt (0), nicht durch den Wert zur Laufzeit jeder Iteration.
Lösung: Delayed Expansion. Mit setlocal enabledelayedexpansion aktivieren, dann !var! statt %var% verwenden:
Faustregel: jedes Skript das Schleifen oder Bedingungen mit Variablen-Änderungen hat, fängt mit setlocal enabledelayedexpansion an. Innerhalb von Code-Blöcken dann immer !var! wenn du den aktuellen Wert willst. %var% ist der Wert beim Block-Eintritt.
setlocal enabledelayedexpansion + !var! in Blöcken.8) Logische Verknüpfungen
Batch hat keine and/or-Operatoren wie andere Sprachen. Aber du kannst Bedingungen verschachteln:
Die Operatoren && und || sind nicht bool'sche Verknüpfungen – sie sind Befehls-Verkettungen basierend auf Exit-Code. Aus Bash oder PowerShell mag dir das vertraut sein.
9) Praktisches Beispiel: Dateien-Cleanup
Alles zusammen – ein Skript das alle Logfiles älter als 30 Tage in einem Verzeichnis löscht:
forfiles ist ein versteckter Helfer der dabei hilft – mit eingebautem Datums-Filter. -30 bedeutet „älter als 30 Tage". Das ist viel einfacher als das Datum aus jeder Datei zu extrahieren und selbst zu vergleichen.
Wenn du es lieber mit reinem for machen willst (oder forfiles nicht verfügbar ist): %%~ti gibt dir das Datum der Datei in der for-Variable. Damit lässt sich dann mit Datums-Arithmetik filtern – ist allerdings ein Aufwand, für den PowerShell deutlich besser geeignet ist.
10) Vergleich: Batch vs. Bash vs. PowerShell
| Konzept | Batch | Bash | PowerShell |
|---|---|---|---|
| if | if X EQU Y (...) | if [ "$x" -eq "$y" ]; then ...; fi | if ($x -eq $y) { ... } |
| else | ) else ( | else | } else { |
| for-Zähler | for /L %%i in (1,1,10) | for i in {1..10} | for ($i=1; $i -le 10; $i++) |
| for-Liste | for %%i in (a b c) | for i in a b c | foreach ($i in @('a','b','c')) |
| Datei zeilenweise | for /F | while read line | Get-Content | foreach |
| Funktionen | :label + call | function name() {...} | function Name { ... } |
| Verzögerte Eval | !var! nach setlocal | kein Problem | kein Problem |
Verdikt: Batch ist deutlich umständlicher als die anderen beiden. Wer kann, schreibt neue Skripte in PowerShell. Aber: alte Batch-Skripte verstehen zu können ist Pflicht – sie sind in Windows-Welten überall.
Zusammenfassung
if BEDINGUNG (BLOCK) else (BLOCK) – Klammern Pflicht, Vergleichsoperatoren EQU/NEQ/LSS/LEQ/GTR/GEQ für Zahlen, == für Strings (in Quotes setzen!). Spezielle if: if exist, if not exist, if defined, if errorlevel N (= N oder größer!), if /i case-insensitive. goto LABEL + :LABEL für Verzweigungen. call :LABEL + exit /b als Funktions-Ersatz. for-Varianten: einfach (Liste), /L (Zähler), /R (rekursiv), /D (nur Dirs), /F (Dateien/Output). %%i in Skripten, %i in der direkten CMD! for /F mit tokens=, delims=, skip= für CSV-Parsing. Delayed Expansion: setlocal enabledelayedexpansion + !var! in Blöcken – Pflicht-Wissen! Logik: AND durch Verschachtelung, OR durch separate ifs, && / || für Exit-Code-Verkettung. forfiles mit /d -N für Datums-Filter. Bei komplexer Logik: PowerShell ist meist die bessere Wahl.
