Toptorials Tutorials WeblogoLogobild kleinLogobild kleinToptorials Tutorials Weblogo
  • ALLE THEMEN IM ÜBERBLICK
  • YouTube
  • INFOS
    • SITEMAP
    • ÜBER TOPTORIALS
✕
            No results See all results

            PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen

            • Startseite
            • Tutorials Windows Automatisierung Powershell 7 Grundkurs
            • PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen

            PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen

            Worum geht es in diesem Teil?

            In diesem fünften Teil des PowerShell-7-Grundkurses benennen wir Dateien und Ordner automatisch um. Vor den bisherigen Namen wird ein frei wählbares Präfix gesetzt.

            Aus diesen Dateien:

            beleg001.jpg
            notiz.txt
            scan001.pdf

            werden mit einem Datumspräfix zum Beispiel:

            2026-08-10_beleg001.jpg
            2026-08-10_notiz.txt
            2026-08-10_scan001.pdf

            Alternativ können Datum und Uhrzeit oder ein eigener Text verwendet werden:

            2026-08-10_14-30-25_scan001.pdf
            Ausgaben_scan001.pdf

            Zum Beispiel:

            Vorher

            Vorher

            Nachher

            NachherZu diesem Teil gehören drei Varianten:

            00_Einfach
            03_SendTo_Elemente_umbenennen
            04_SendTo_Ordnerinhalt_umbenennen

            Die einfache Variante benennt die Dateien im aktuellen Arbeitsordner um.

            Die zweite Variante benennt genau die Dateien und Ordner um, die im Windows-Explorer markiert und über Senden an übergeben wurden. Bei einem ausgewählten Ordner wird nur der Ordner selbst umbenannt, nicht sein Inhalt.

            Die dritte Variante erhält einen oder mehrere Ordner über Senden an und benennt die direkt darin enthaltenen Dateien um. Die übergebenen Ordner selbst und mögliche Unterordner bleiben unverändert.

            Was ist das Ziel?

            Das Ziel ist ein verständliches und möglichst sicheres PowerShell-7-Werkzeug für wiederkehrende Umbenennungen.

            Dabei gelten wichtige Sicherheitsregeln:

            Zuerst wird nur getestet.
            Im Testmodus werden keine Dateien oder Ordner umbenannt.
            Vorhandene Ziele werden nicht überschrieben.
            Bereits vorhandene Präfixe werden erkannt.
            Leere oder ungültige Präfixe werden abgewiesen.
            Vor dem echten Umbenennen muss JA eingegeben werden.
            Fehler werden kontrolliert abgefangen und gezählt.

            Die Meldungen können wahlweise nur im Fenster angezeigt, als Logdatei gespeichert, in die Zwischenablage kopiert oder über beide zusätzlichen Wege ausgegeben werden.

            Warum ist dieser Teil wichtig?

            In diesem Teil lernen wir mehrere wichtige PowerShell-Grundlagen kennen:

            Switch-Parameter und Startargumente
            Dateien und Ordner mit Get-Item und Get-ChildItem erfassen
            Dateinamen mit einem Präfix zusammensetzen
            Datum und Uhrzeit mit Get-Date formatieren
            Texte mit StartsWith() vergleichen
            Ungültige Dateinamenzeichen mit IndexOfAny() erkennen
            Pfade mit Split-Path zerlegen
            Pfade mit Join-Path zusammensetzen
            Objekte mit PSCustomObject vorbereiten
            Objekte mit Sort-Object sortieren
            Elemente mit Rename-Item umbenennen
            Fehler mit try und catch behandeln
            Protokolle und Statistiken erstellen
            Text in die Zwischenablage kopieren

            Besonders wichtig ist die Trennung zwischen Planung und tatsächlicher Änderung. Die SendTo-Varianten stellen zunächst Umbenennungspläne zusammen. Erst danach werden die geplanten Vorgänge im Testmodus angezeigt oder im Echtmodus ausgeführt.

            Hinweis zur Kursreihe

            Diese PowerShell-7-Reihe ist Teil einer größeren Windows-Automatisierungsreihe.

            Viele Aufgaben werden in mehreren Sprachen umgesetzt:

            Batch
            PowerShell 7
            Python

            Dadurch kann man vergleichen, wie dieselbe Aufgabe in unterschiedlichen Sprachen gelöst wird.

            Der Code ist bewusst ausführlich aufgebaut. Funktionen oder Klassen wären möglich, würden diesen Grundkurs aber unnötig komplizierter machen. Deshalb bleiben Variablen, Schleifen, Prüfungen, Zähler und Meldungen gut sichtbar.

            Downloads zu diesem Teil

            Für diesen Teil gibt es drei PowerShell-7-Skripte und die dazugehörigen Starter-Batchdateien.

            Dateien für PowerShell 7 Grundkurs Teil 005:


            Download PowerShell 7 Grundkurs: 005_Dateien_mit_Praefix_umbenennen als ZIP-Datei.

            Entpacken nach:

            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs

            Falls der Ordner noch nicht existiert, lege ihn vorher im Explorer an.

            Nach dem Entpacken entsteht dort:

            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs\005_Dateien_mit_Praefix_umbenennen

            Darin befinden sich diese drei Unterordner:

            00_Einfach
            03_SendTo_Elemente_umbenennen
            04_SendTo_Ordnerinhalt_umbenennen

            Testumgebung zum Mitmachen

            Für diese Tutorialreihe gibt es zusätzlich eine vorbereitete Testumgebung. Sie enthält Beispieldateien und Ordner, an denen alle drei Varianten gefahrlos ausprobiert werden können.

            Testumgebung für Windows-Automatisierung:

            Download TOPTORIALS_Testdaten_Windows_Automatisierung_V001.zip

            Entpacken nach:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH

            Falls der Ordner C:\TOPTORIALS_CODE\1000_TESTBEREICH noch nicht existiert, lege ihn vorher im Explorer an.

            Für diesen PowerShell-7-Grundkurs kann der entpackte Ordner so benannt werden:

            TOPTORIALS_Testdaten_Windows_Automatisierung_Powershell_7_V001

            Der vollständige Testpfad für diesen Teil lautet:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Powershell_7_V001\005_Dateien_mit_Praefix_umbenennen

            Die Testdaten sind folgendermaßen aufgebaut:

            005_Dateien_mit_Praefix_umbenennen
            ├── 01_Aktueller_Ordner
            │   ├── beleg001.jpg
            │   ├── Einnahmen_scan_alt.pdf
            │   ├── notiz.txt
            │   ├── scan001.pdf
            │   └── scan002.pdf
            ├── 02_SendTo_Elemente
            │   ├── dokument_a.pdf
            │   ├── dokument_b.pdf
            │   ├── Einzelordner_A
            │   ├── Einzelordner_B
            │   └── kassenbon.jpg
            └── 03_SendTo_Ordnerinhalt
                ├── Kasse
                │   ├── bon001.pdf
                │   └── bon002.pdf
                ├── Scans_Ausgaben
                │   ├── quittung.txt
                │   ├── rechnung_buero.pdf
                │   └── tankbeleg.jpg
                ├── Scans_Einnahmen
                │   ├── beleg_maerz.pdf
                │   ├── scan001.pdf
                │   └── scan002.pdf
                └── Sonstige
                    ├── dokument.pdf
                    └── info.txt

            Sicherheitshinweis

            Wichtiger Hinweis:

            Die Skripte werden auf eigene Verantwortung verwendet. Teste sie zuerst in einer separaten Testumgebung und niemals direkt mit wichtigen Originaldateien.

            Solange _test im Namen der Starter-Batchdatei steht, wird das PowerShell-Skript mit dem Schalter -Test gestartet. In diesem Modus werden keine Dateien und keine Ordner umbenannt.

            Erst nachdem alle angezeigten Zielnamen geprüft wurden, kann ausschließlich _test aus dem Namen der Starter-Batchdatei entfernt werden. Beim echten Lauf erscheint zusätzlich eine Sicherheitsabfrage. Nur die exakte Eingabe JA startet das Umbenennen.

            Ein gleichnamiges Ziel wird nicht überschrieben. Trotzdem sollte die echte Ausführung zuerst mit Kopien unwichtiger Dateien getestet werden. Besonders bei Datum und Uhrzeit ist zu beachten, dass ein zweiter Lauf mit einem inzwischen veränderten Präfix einen weiteren Präfixbestandteil ergänzen kann.

            Enthaltene Dateien

            Variante 1: Einfach

            00_Einfach
            ├── 005_dateien_mit_praefix_umbenennen.ps1
            └── 005_dateien_mit_praefix_umbenennen_starter_batch_test.bat

            Variante 2: Ausgewählte SendTo-Elemente umbenennen

            03_SendTo_Elemente_umbenennen
            ├── 005_sendto_elemente_mit_praefix_umbenennen.ps1
            └── 005_sendto_elemente_mit_praefix_umbenennen_starter_batch_test.bat

            Variante 3: Dateien in ausgewählten SendTo-Ordnern umbenennen

            04_SendTo_Ordnerinhalt_umbenennen
            ├── 005_sendto_ordnerinhalt_mit_praefix_umbenennen.ps1
            └── 005_sendto_ordnerinhalt_mit_praefix_umbenennen_starter_batch_test.bat

            Präfix einstellen

            In allen drei PowerShell-Dateien stehen dieselben drei vorbereiteten Präfixvarianten. Es darf immer nur eine Zeile aktiv sein.

            Variante 1: Aktuelles Datum

            $praefix = Get-Date -Format "yyyy-MM-dd_"

            Ein möglicher neuer Name lautet:

            2026-08-10_rechnung.pdf

            Variante 2: Datum und Uhrzeit

            # $praefix = Get-Date -Format "yyyy-MM-dd_HH-mm-ss_"

            Zum Aktivieren wird das Kommentarzeichen entfernt und die bisher aktive Variante auskommentiert:

            # $praefix = Get-Date -Format "yyyy-MM-dd_"
            $praefix = Get-Date -Format "yyyy-MM-dd_HH-mm-ss_"

            Ein möglicher neuer Name lautet:

            2026-08-10_14-30-25_rechnung.pdf

            Variante 3: Eigener Text

            # $praefix = "Ausgaben_"

            Nach dem Aktivieren entsteht zum Beispiel:

            Ausgaben_rechnung.pdf

            Zeichen wie \, /, :, *, ?, ", <, > und | sind in Windows-Dateinamen nicht zulässig. Das Skript prüft das eingestellte Präfix vor der Verarbeitung.

            Zusätzliche Ausgabe einstellen

            Auch bei der Ausgabe darf immer nur eine der vier vorbereiteten Varianten aktiv sein:

            Nur Bildschirmausgabe
            Logdatei erstellen
            Nur in die Zwischenablage kopieren
            Logdatei erstellen und in die Zwischenablage kopieren

            Die Einstellung erfolgt über zwei Wahrheitswerte:

            $logDateiErstellen = $false
            $zwischenablageVerwenden = $false

            $true schaltet eine Funktion ein, $false schaltet sie aus.

            Variante 1: Dateien im aktuellen Ordner umbenennen

            Die einfache Variante wird gemeinsam mit ihrer Starter-Batchdatei in den Ordner kopiert, dessen Dateien umbenannt werden sollen.

            Für die Testumgebung ist das:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_Powershell_7_V001\005_Dateien_mit_Praefix_umbenennen\01_Aktueller_Ordner

            Danach wird diese Datei per Doppelklick gestartet:

            005_dateien_mit_praefix_umbenennen_starter_batch_test.bat

            Im Testmodus erscheint zum Beispiel:

            WÜRDE UMBENENNEN: "beleg001.jpg" zu "2026-08-10_beleg001.jpg"
            WÜRDE UMBENENNEN: "scan001.pdf" zu "2026-08-10_scan001.pdf"

            Die PowerShell-Datei, die Starter-Batchdatei und bereits vorhandene Protokolldateien werden geschützt und übersprungen.

            Wenn alles richtig aussieht, wird nur _test aus dem Namen der Starter-Batchdatei entfernt:

            005_dateien_mit_praefix_umbenennen_starter_batch.bat

            Die PowerShell-Datei selbst wird nicht umbenannt.

            Der komplette Code der einfachen PowerShell-7-Datei

            Die Datei heißt:

            005_dateien_mit_praefix_umbenennen.ps1
            # ============================================================
            # TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            # Script: 005_dateien_mit_praefix_umbenennen.ps1
            # Beschreibung: Benennt Dateien im Skriptordner mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-08
            # ============================================================
            
            param (
                [switch]$Test
            )
            
            Write-Host ""
            Write-Host "Dateien werden mit einem Präfix umbenannt..."
            Write-Host ""
            
            $basisOrdner = (Get-Location).Path
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            $praefix = Get-Date -Format "yyyy-MM-dd_"
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # $praefix = Get-Date -Format "yyyy-MM-dd_HH-mm-ss_"
            
            # Variante 3: Eigener Text
            # $praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            $logDateiErstellen = $false
            $zwischenablageVerwenden = $false
            
            # Variante 2: Logdatei erstellen
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $false
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # $logDateiErstellen = $false
            # $zwischenablageVerwenden = $true
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $true
            
            
            # ------------------------------------------------------------
            # Präfix prüfen
            # ------------------------------------------------------------
            
            $ungueltigeZeichen = [System.IO.Path]::GetInvalidFileNameChars()
            
            if ([string]::IsNullOrWhiteSpace($praefix) -or $praefix.IndexOfAny($ungueltigeZeichen) -ge 0) {
                Write-Host "FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen."
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            if ($Test) {
                $modusText = "TESTMODUS"
            }
            else {
                $modusText = "ECHTMODUS"
            }
            
            $anzahlUmbenannt = 0
            $anzahlUebersprungen = 0
            $anzahlFehler = 0
            $protokoll = @()
            
            $protokoll += "Dateien werden mit einem Präfix umbenannt."
            $protokoll += "Modus: $modusText"
            $protokoll += "Präfix: $praefix"
            $protokoll += "Verarbeiteter Ordner: $basisOrdner"
            $protokoll += ""
            
            Write-Host "Modus: $modusText"
            Write-Host "Präfix: $praefix"
            Write-Host "Verarbeiteter Ordner: $basisOrdner"
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if (-not $Test) {
                Write-Host "ACHTUNG: Dieses Skript wird Dateien wirklich umbenennen."
                Write-Host ""
            
                $antwort = Read-Host "Zum Fortfahren JA eingeben"
            
                if ($antwort -ne "JA") {
                    Write-Host ""
                    Write-Host "Abgebrochen."
                    Write-Host ""
                    Read-Host "Drücke Enter zum Beenden"
                    exit
                }
            }
            
            
            # ------------------------------------------------------------
            # Dateien erfassen
            # PowerShell-Skript, Starter-Batchdatei und alte Protokolle
            # werden geschützt und nicht umbenannt.
            # ------------------------------------------------------------
            
            $dateien = @(Get-ChildItem -LiteralPath $basisOrdner -File)
            
            foreach ($datei in $dateien) {
                $istGeschuetzt =
                    $datei.FullName -eq $PSCommandPath -or
                    $datei.Name -like "005_dateien_mit_praefix_umbenennen_starter_batch*.bat" -or
                    $datei.Name -like "umbenennprotokoll_*.log"
            
                if ($istGeschuetzt) {
                    $meldung = "ÜBERSPRUNGEN: `"$($datei.Name)`" - Skript- oder Protokolldatei ist geschützt"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                if ($datei.Name.StartsWith($praefix, [System.StringComparison]::OrdinalIgnoreCase)) {
                    $meldung = "ÜBERSPRUNGEN: `"$($datei.Name)`" - Präfix ist bereits am Anfang enthalten"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                $neuerName = $praefix + $datei.Name
                $zielPfad = Join-Path -Path $basisOrdner -ChildPath $neuerName
            
                if (Test-Path -LiteralPath $zielPfad) {
                    $meldung = "ÜBERSPRUNGEN: `"$($datei.Name)`" - Ziel existiert bereits: `"$zielPfad`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                if ($Test) {
                    $meldung = "WÜRDE UMBENENNEN: `"$($datei.Name)`" zu `"$neuerName`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                    continue
                }
            
                try {
                    Rename-Item -LiteralPath $datei.FullName -NewName $neuerName -ErrorAction Stop
            
                    $meldung = "UMBENANNT: `"$($datei.Name)`" zu `"$neuerName`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                }
                catch {
                    $fehlerText = $_.Exception.Message
                    $meldung = "FEHLER: `"$($datei.Name)`" konnte nicht umbenannt werden. Grund: $fehlerText"
            
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlFehler++
                }
            }
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            $protokoll += ""
            $protokoll += "Fertig."
            
            Write-Host ""
            Write-Host "Fertig."
            Write-Host ""
            
            if ($Test) {
                $meldung1 = "Anzahl Dateien, die umbenannt würden: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
                Write-Host ""
                Write-Host "Es wurden keine Dateien umbenannt."
                Write-Host "Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei."
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
                $protokoll += "Es wurden keine Dateien umbenannt."
            }
            else {
                $meldung1 = "Anzahl umbenannt: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
            }
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            $protokollText = $protokoll -join [Environment]::NewLine
            $zeitstempel = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
            $logDatei = Join-Path -Path $basisOrdner -ChildPath "umbenennprotokoll_$zeitstempel.log"
            
            if ($logDateiErstellen) {
                try {
                    $protokollText | Set-Content -LiteralPath $logDatei -Encoding UTF8 -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde erstellt:"
                    Write-Host $logDatei
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: $($_.Exception.Message)"
                }
            }
            
            if ($zwischenablageVerwenden) {
                try {
                    $protokollText | Set-Clipboard -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde zusätzlich in die Zwischenablage kopiert."
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht in die Zwischenablage kopiert werden. Grund: $($_.Exception.Message)"
                }
            }
            
            Write-Host ""
            Read-Host "Drücke Enter zum Beenden"

            Code der einfachen PowerShell-7-Datei erklärt

            Aktuellen Arbeitsordner ermitteln

            $basisOrdner = (Get-Location).Path

            Get-Location liefert den aktuellen Arbeitsordner. Die Starter-Batchdatei wechselt vorher mit cd /d "%~dp0" in ihren eigenen Ordner. Dadurch entspricht der Arbeitsordner dem Ordner, in den beide Skriptdateien kopiert wurden.

            Ungültige Zeichen prüfen

            $ungueltigeZeichen = [System.IO.Path]::GetInvalidFileNameChars()
            
            if ([string]::IsNullOrWhiteSpace($praefix) -or $praefix.IndexOfAny($ungueltigeZeichen) -ge 0) {
                # Fehlermeldung und Abbruch
            }

            GetInvalidFileNameChars() liefert die Zeichen, die in einem Dateinamen nicht erlaubt sind. IsNullOrWhiteSpace() erkennt einen leeren Präfix oder einen Präfix, der nur aus Leerzeichen besteht.

            IndexOfAny() sucht nach einem der ungültigen Zeichen. Das Ergebnis -1 bedeutet, dass keines gefunden wurde. Ein Ergebnis größer oder gleich null bedeutet, dass mindestens ein ungültiges Zeichen vorhanden ist.

            Geschützte Dateien erkennen

            $istGeschuetzt =
                $datei.FullName -eq $PSCommandPath -or
                $datei.Name -like "005_dateien_mit_praefix_umbenennen_starter_batch*.bat" -or
                $datei.Name -like "umbenennprotokoll_*.log"

            $PSCommandPath enthält den vollständigen Pfad der ausgeführten PowerShell-Datei. Zusätzlich werden passende Starter-Batchdateien und ältere Protokolle über -like mit Platzhaltern erkannt. Diese Dateien erhalten kein Präfix.

            Vorhandenes Präfix erkennen

            if ($datei.Name.StartsWith(
                $praefix,
                [System.StringComparison]::OrdinalIgnoreCase
            ))

            StartsWith() prüft, ob der Name bereits mit dem eingestellten Präfix beginnt. OrdinalIgnoreCase sorgt für einen direkten technischen Vergleich ohne Beachtung der Groß- und Kleinschreibung.

            Neuen Namen und Zielpfad bilden

            $neuerName = $praefix + $datei.Name
            $zielPfad = Join-Path -Path $basisOrdner -ChildPath $neuerName

            Der neue Name entsteht durch die Verbindung von Präfix und bisherigem Namen. Join-Path verbindet anschließend den Ordnerpfad und den neuen Namen zu einem vollständigen Zielpfad.

            Datei sicher umbenennen

            try {
                Rename-Item -LiteralPath $datei.FullName
                            -NewName $neuerName
                            -ErrorAction Stop
            }
            catch {
                $fehlerText = $_.Exception.Message
            }

            Rename-Item benennt die Datei um. -LiteralPath behandelt mögliche Sonderzeichen im Pfad wörtlich. -ErrorAction Stop leitet auch nicht beendende Fehler an den catch-Block weiter. Dort enthält $_.Exception.Message den lesbaren Meldungstext.

            Der komplette Code der einfachen Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            REM Script: 005_dateien_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet das PowerShell-7-Skript im Testmodus.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-08
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird -Test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                pwsh -ExecutionPolicy Bypass -File "005_dateien_mit_praefix_umbenennen.ps1" -Test
            ) else (
                pwsh -ExecutionPolicy Bypass -File "005_dateien_mit_praefix_umbenennen.ps1"
            )

            Code der einfachen Starter-Batchdatei erklärt

            echo %~n0 | find /i "_test" >nul

            %~n0 liefert den Namen der gestarteten Batchdatei ohne Dateiendung. find /i sucht darin ohne Beachtung der Groß- und Kleinschreibung nach _test.

            Wurde _test gefunden, wird der Schalter -Test an PowerShell übergeben:

            pwsh -ExecutionPolicy Bypass -File "005_dateien_mit_praefix_umbenennen.ps1" -Test

            Ohne _test startet dieselbe PowerShell-Datei im Echtmodus.

            Variante 2: Ausgewählte Dateien und Ordner über SendTo umbenennen

            Diese Variante verarbeitet genau die Elemente, die im Explorer markiert wurden.

            Im Testordner 02_SendTo_Elemente können zum Beispiel diese Elemente gemeinsam markiert werden:

            dokument_a.pdf
            kassenbon.jpg
            Einzelordner_A

            Nach Rechtsklick – Senden an zeigt der Testmodus die geplanten neuen vollständigen Pfade an.

            Wichtig: Wird Einzelordner_A übergeben, erhält nur dieser Ordner ein Präfix. Sein möglicher Inhalt wird nicht verarbeitet.

            Der komplette Code der SendTo-Elemente-PowerShell-Datei

            Die Datei heißt:

            005_sendto_elemente_mit_praefix_umbenennen.ps1
            # ============================================================
            # TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            # Script: 005_sendto_elemente_mit_praefix_umbenennen.ps1
            # Beschreibung: Benennt über SendTo übergebene Dateien und Ordner mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-08
            # ============================================================
            
            param (
                [switch]$Test,
            
                [Parameter(ValueFromRemainingArguments = $true)]
                [string[]]$Elemente
            )
            
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Prüfen, ob mindestens ein Element übergeben wurde
            # ------------------------------------------------------------
            
            if (-not $Elemente -or $Elemente.Count -eq 0) {
                Write-Host "Bitte sende mindestens eine Datei oder einen Ordner an dieses Skript."
                Write-Host ""
                Write-Host "Du kannst Dateien oder Ordner im Explorer markieren,"
                Write-Host "rechts anklicken und anschließend 'Senden an' verwenden."
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            $praefix = Get-Date -Format "yyyy-MM-dd_"
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # $praefix = Get-Date -Format "yyyy-MM-dd_HH-mm-ss_"
            
            # Variante 3: Eigener Text
            # $praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            $logDateiErstellen = $false
            $zwischenablageVerwenden = $false
            
            # Variante 2: Logdatei erstellen
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $false
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # $logDateiErstellen = $false
            # $zwischenablageVerwenden = $true
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $true
            
            
            # ------------------------------------------------------------
            # Präfix und Modus vorbereiten
            # ------------------------------------------------------------
            
            $ungueltigeZeichen = [System.IO.Path]::GetInvalidFileNameChars()
            
            if ([string]::IsNullOrWhiteSpace($praefix) -or $praefix.IndexOfAny($ungueltigeZeichen) -ge 0) {
                Write-Host "FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen."
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            if ($Test) {
                $modusText = "TESTMODUS"
            }
            else {
                $modusText = "ECHTMODUS"
            }
            
            $anzahlUmbenannt = 0
            $anzahlUebersprungen = 0
            $anzahlFehler = 0
            $protokoll = @()
            $plaene = @()
            
            $protokoll += "Übergebene Dateien und Ordner werden mit einem Präfix umbenannt."
            $protokoll += "Modus: $modusText"
            $protokoll += "Präfix: $praefix"
            $protokoll += ""
            
            Write-Host "Dateien und Ordner werden mit einem Präfix umbenannt..."
            Write-Host ""
            Write-Host "Modus: $modusText"
            Write-Host "Präfix: $praefix"
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Umbenennungen vorbereiten und prüfen
            # ------------------------------------------------------------
            
            $eindeutigeElemente = @($Elemente | Select-Object -Unique)
            
            foreach ($elementPfad in $eindeutigeElemente) {
                if (-not (Test-Path -LiteralPath $elementPfad)) {
                    $meldung = "ÜBERSPRUNGEN: Pfad wurde nicht gefunden: `"$elementPfad`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                try {
                    $element = Get-Item -LiteralPath $elementPfad -Force -ErrorAction Stop
                }
                catch {
                    $meldung = "FEHLER: Element konnte nicht gelesen werden: `"$elementPfad`". Grund: $($_.Exception.Message)"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlFehler++
                    continue
                }
            
                $elternPfad = Split-Path -LiteralPath $element.FullName
            
                if ([string]::IsNullOrWhiteSpace($elternPfad)) {
                    $meldung = "ÜBERSPRUNGEN: Eine Laufwerkswurzel kann nicht umbenannt werden: `"$($element.FullName)`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                if ($element.Name.StartsWith($praefix, [System.StringComparison]::OrdinalIgnoreCase)) {
                    $meldung = "ÜBERSPRUNGEN: `"$($element.FullName)`" - Präfix ist bereits am Anfang enthalten"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                $neuerName = $praefix + $element.Name
                $zielPfad = Join-Path -Path $elternPfad -ChildPath $neuerName
            
                if (Test-Path -LiteralPath $zielPfad) {
                    $meldung = "ÜBERSPRUNGEN: `"$($element.FullName)`" - Ziel existiert bereits: `"$zielPfad`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                $plaene += [PSCustomObject]@{
                    Quelle    = $element.FullName
                    AlterName = $element.Name
                    NeuerName = $neuerName
                    Ziel      = $zielPfad
                }
            }
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if (-not $Test -and $plaene.Count -gt 0) {
                Write-Host "ACHTUNG: Dieses Skript wird die übergebenen Dateien und Ordner wirklich umbenennen."
                Write-Host ""
            
                $antwort = Read-Host "Zum Fortfahren JA eingeben"
            
                if ($antwort -ne "JA") {
                    Write-Host ""
                    Write-Host "Abgebrochen."
                    Write-Host ""
                    Read-Host "Drücke Enter zum Beenden"
                    exit
                }
            
                Write-Host ""
            }
            
            
            # ------------------------------------------------------------
            # Dateien und Ordner umbenennen
            # Längere Pfade werden zuerst verarbeitet. Dadurch können auch
            # verschachtelt übergebene Elemente kontrollierter behandelt werden.
            # ------------------------------------------------------------
            
            $plaene = @($plaene | Sort-Object { $_.Quelle.Length } -Descending)
            
            foreach ($plan in $plaene) {
                if ($Test) {
                    $meldung = "WÜRDE UMBENENNEN: `"$($plan.Quelle)`" zu `"$($plan.Ziel)`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                    continue
                }
            
                try {
                    Rename-Item -LiteralPath $plan.Quelle -NewName $plan.NeuerName -ErrorAction Stop
            
                    $meldung = "UMBENANNT: `"$($plan.Quelle)`" zu `"$($plan.Ziel)`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                }
                catch {
                    $meldung = "FEHLER: `"$($plan.Quelle)`" konnte nicht umbenannt werden. Grund: $($_.Exception.Message)"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlFehler++
                }
            }
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            $protokoll += ""
            $protokoll += "Fertig."
            
            Write-Host ""
            Write-Host "Fertig."
            Write-Host ""
            
            if ($Test) {
                $meldung1 = "Anzahl Elemente, die umbenannt würden: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
                Write-Host ""
                Write-Host "Es wurden keine Dateien oder Ordner umbenannt."
                Write-Host "Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei."
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
                $protokoll += "Es wurden keine Dateien oder Ordner umbenannt."
            }
            else {
                $meldung1 = "Anzahl umbenannt: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
            }
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            $protokollText = $protokoll -join [Environment]::NewLine
            $zeitstempel = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
            $logDatei = Join-Path -Path $PSScriptRoot -ChildPath "umbenennprotokoll_elemente_$zeitstempel.log"
            
            if ($logDateiErstellen) {
                try {
                    $protokollText | Set-Content -LiteralPath $logDatei -Encoding UTF8 -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde erstellt:"
                    Write-Host $logDatei
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: $($_.Exception.Message)"
                }
            }
            
            if ($zwischenablageVerwenden) {
                try {
                    $protokollText | Set-Clipboard -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde zusätzlich in die Zwischenablage kopiert."
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht in die Zwischenablage kopiert werden. Grund: $($_.Exception.Message)"
                }
            }
            
            Write-Host ""
            Read-Host "Drücke Enter zum Beenden"

            Code der SendTo-Elemente-Datei erklärt

            Mehrere übergebene Pfade empfangen

            param (
                [switch]$Test,
            
                [Parameter(ValueFromRemainingArguments = $true)]
                [string[]]$Elemente
            )

            [string[]] kennzeichnet ein Array aus Textwerten. Darin können mehrere übergebene Datei- und Ordnerpfade gespeichert werden. ValueFromRemainingArguments nimmt die noch vorhandenen Startargumente auf.

            Doppelte Übergaben entfernen

            $eindeutigeElemente = @($Elemente | Select-Object -Unique)

            Select-Object -Unique entfernt identische Mehrfacheinträge. Die äußere Array-Konstruktion @(...) sorgt dafür, dass das Ergebnis auch bei nur einem Element weiterhin als Sammlung behandelt werden kann.

            Elternpfad für Dateien und Ordner ermitteln

            $elternPfad = Split-Path -LiteralPath $element.FullName

            Split-Path gibt hier den übergeordneten Pfad zurück. Das funktioniert einheitlich für Dateien und Ordner. -LiteralPath verhindert, dass Zeichen wie eckige Klammern als Platzhalter ausgewertet werden.

            Aus:

            C:\Test\Dokumente\Rechnung.pdf

            wird:

            C:\Test\Dokumente

            Aus:

            C:\Test\Dokumente\Archiv

            wird ebenfalls:

            C:\Test\Dokumente

            Die anschließende Prüfung schützt Laufwerkswurzeln, für die kein normaler übergeordneter Ordner ermittelt werden kann.

            Umbenennungen zunächst planen

            $plaene += [PSCustomObject]@{
                Quelle    = $element.FullName
                AlterName = $element.Name
                NeuerName = $neuerName
                Ziel      = $zielPfad
            }

            Für jede gültige Umbenennung entsteht ein Objekt mit vier benannten Eigenschaften. Die Änderungen sind an dieser Stelle nur geplant; Rename-Item wurde noch nicht ausgeführt.

            Längere Pfade zuerst verarbeiten

            $plaene = @($plaene | Sort-Object { $_.Quelle.Length } -Descending)

            Wenn gleichzeitig ein Ordner und ein darin liegendes Element markiert wurden, wird der längere und damit meist tiefer liegende Pfad zuerst verarbeitet. Würde zuerst der übergeordnete Ordner umbenannt, wäre der zuvor gespeicherte Pfad des enthaltenen Elements nicht mehr gültig.

            Der komplette Code der SendTo-Elemente-Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            REM Script: 005_sendto_elemente_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet die SendTo-Variante für Dateien und Ordner.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-08
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird -Test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                pwsh -ExecutionPolicy Bypass -File "005_sendto_elemente_mit_praefix_umbenennen.ps1" -Test %*
            ) else (
                pwsh -ExecutionPolicy Bypass -File "005_sendto_elemente_mit_praefix_umbenennen.ps1" %*
            )

            Variante 3: Dateien in ausgewählten Ordnern über SendTo umbenennen

            Diese Variante erwartet einen oder mehrere Ordner. Sie erfasst die Dateien, die direkt in diesen Ordnern liegen, und versieht deren Namen mit dem Präfix.

            Für einen Test können im Ordner 03_SendTo_Ordnerinhalt beispielsweise diese Ordner gemeinsam markiert werden:

            Kasse
            Scans_Ausgaben
            Scans_Einnahmen
            Sonstige

            Die Ordnernamen selbst bleiben unverändert. Auch mögliche Unterordner werden nicht durchsucht. Dadurch ist der Verarbeitungsumfang klar begrenzt.

            Der komplette Code der SendTo-Ordnerinhalt-PowerShell-Datei

            Die Datei heißt:

            005_sendto_ordnerinhalt_mit_praefix_umbenennen.ps1
            # ============================================================
            # TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            # Script: 005_sendto_ordnerinhalt_mit_praefix_umbenennen.ps1
            # Beschreibung: Benennt Dateien in über SendTo übergebenen Ordnern mit einem Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-08
            # ============================================================
            
            param (
                [switch]$Test,
            
                [Parameter(ValueFromRemainingArguments = $true)]
                [string[]]$Elemente
            )
            
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Prüfen, ob mindestens ein Element übergeben wurde
            # ------------------------------------------------------------
            
            if (-not $Elemente -or $Elemente.Count -eq 0) {
                Write-Host "Bitte sende mindestens einen Ordner an dieses Skript."
                Write-Host ""
                Write-Host "Du kannst einen oder mehrere Ordner im Explorer markieren,"
                Write-Host "rechts anklicken und anschließend 'Senden an' verwenden."
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            
            # ------------------------------------------------------------
            # Gewünschte Präfixvariante auswählen
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Aktuelles Datum
            $praefix = Get-Date -Format "yyyy-MM-dd_"
            
            # Variante 2: Aktuelles Datum und aktuelle Uhrzeit
            # $praefix = Get-Date -Format "yyyy-MM-dd_HH-mm-ss_"
            
            # Variante 3: Eigener Text
            # $praefix = "Ausgaben_"
            
            
            # ------------------------------------------------------------
            # Welche zusätzliche Ausgabe soll erstellt werden?
            # Wichtig: Immer nur EINE der folgenden Varianten aktiv lassen.
            # ------------------------------------------------------------
            
            # Variante 1: Nur Bildschirmausgabe
            $logDateiErstellen = $false
            $zwischenablageVerwenden = $false
            
            # Variante 2: Logdatei erstellen
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $false
            
            # Variante 3: Nur in die Zwischenablage kopieren
            # $logDateiErstellen = $false
            # $zwischenablageVerwenden = $true
            
            # Variante 4: Logdatei erstellen und in die Zwischenablage kopieren
            # $logDateiErstellen = $true
            # $zwischenablageVerwenden = $true
            
            
            # ------------------------------------------------------------
            # Präfix und Modus vorbereiten
            # ------------------------------------------------------------
            
            $ungueltigeZeichen = [System.IO.Path]::GetInvalidFileNameChars()
            
            if ([string]::IsNullOrWhiteSpace($praefix) -or $praefix.IndexOfAny($ungueltigeZeichen) -ge 0) {
                Write-Host "FEHLER: Das eingestellte Präfix ist leer oder enthält ungültige Zeichen."
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            if ($Test) {
                $modusText = "TESTMODUS"
            }
            else {
                $modusText = "ECHTMODUS"
            }
            
            $anzahlUmbenannt = 0
            $anzahlUebersprungen = 0
            $anzahlFehler = 0
            $anzahlOrdner = 0
            $protokoll = @()
            $plaene = @()
            
            $protokoll += "Dateien in übergebenen Ordnern werden mit einem Präfix umbenannt."
            $protokoll += "Modus: $modusText"
            $protokoll += "Präfix: $praefix"
            $protokoll += ""
            
            Write-Host "Dateien in übergebenen Ordnern werden mit einem Präfix umbenannt..."
            Write-Host ""
            Write-Host "Modus: $modusText"
            Write-Host "Präfix: $praefix"
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Ordner und direkt enthaltene Dateien erfassen
            # Unterordner werden nicht durchsucht.
            # ------------------------------------------------------------
            
            $eindeutigeElemente = @($Elemente | Select-Object -Unique)
            
            foreach ($elementPfad in $eindeutigeElemente) {
                if (-not (Test-Path -LiteralPath $elementPfad -PathType Container)) {
                    $meldung = "ÜBERSPRUNGEN: Der übergebene Pfad ist kein Ordner: `"$elementPfad`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUebersprungen++
                    continue
                }
            
                try {
                    $ordner = Get-Item -LiteralPath $elementPfad -Force -ErrorAction Stop
                    $dateien = @(Get-ChildItem -LiteralPath $ordner.FullName -File -Force -ErrorAction Stop)
                    $anzahlOrdner++
            
                    Write-Host "Ordner wird verarbeitet:"
                    Write-Host $ordner.FullName
                    Write-Host ""
            
                    $protokoll += "Verarbeiteter Ordner: $($ordner.FullName)"
                }
                catch {
                    $meldung = "FEHLER: Ordnerinhalt konnte nicht gelesen werden: `"$elementPfad`". Grund: $($_.Exception.Message)"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlFehler++
                    continue
                }
            
                foreach ($datei in $dateien) {
                    if ($datei.Name.StartsWith($praefix, [System.StringComparison]::OrdinalIgnoreCase)) {
                        $meldung = "ÜBERSPRUNGEN: `"$($datei.FullName)`" - Präfix ist bereits am Anfang enthalten"
                        Write-Host $meldung
                        $protokoll += $meldung
                        $anzahlUebersprungen++
                        continue
                    }
            
                    $neuerName = $praefix + $datei.Name
                    $zielPfad = Join-Path -Path $ordner.FullName -ChildPath $neuerName
            
                    if (Test-Path -LiteralPath $zielPfad) {
                        $meldung = "ÜBERSPRUNGEN: `"$($datei.FullName)`" - Zieldatei existiert bereits: `"$zielPfad`""
                        Write-Host $meldung
                        $protokoll += $meldung
                        $anzahlUebersprungen++
                        continue
                    }
            
                    $plaene += [PSCustomObject]@{
                        Quelle    = $datei.FullName
                        AlterName = $datei.Name
                        NeuerName = $neuerName
                        Ziel      = $zielPfad
                    }
                }
            
                $protokoll += ""
            }
            
            
            # ------------------------------------------------------------
            # Sicherheitsabfrage bei der echten Ausführung
            # ------------------------------------------------------------
            
            if (-not $Test -and $plaene.Count -gt 0) {
                Write-Host "ACHTUNG: Dieses Skript wird Dateien in den übergebenen Ordnern wirklich umbenennen."
                Write-Host ""
            
                $antwort = Read-Host "Zum Fortfahren JA eingeben"
            
                if ($antwort -ne "JA") {
                    Write-Host ""
                    Write-Host "Abgebrochen."
                    Write-Host ""
                    Read-Host "Drücke Enter zum Beenden"
                    exit
                }
            
                Write-Host ""
            }
            
            
            # ------------------------------------------------------------
            # Dateien umbenennen
            # ------------------------------------------------------------
            
            foreach ($plan in $plaene) {
                if ($Test) {
                    $meldung = "WÜRDE UMBENENNEN: `"$($plan.Quelle)`" zu `"$($plan.Ziel)`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                    continue
                }
            
                try {
                    Rename-Item -LiteralPath $plan.Quelle -NewName $plan.NeuerName -ErrorAction Stop
            
                    $meldung = "UMBENANNT: `"$($plan.Quelle)`" zu `"$($plan.Ziel)`""
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                }
                catch {
                    $meldung = "FEHLER: `"$($plan.Quelle)`" konnte nicht umbenannt werden. Grund: $($_.Exception.Message)"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlFehler++
                }
            }
            
            
            # ------------------------------------------------------------
            # Zusammenfassung
            # ------------------------------------------------------------
            
            $protokoll += ""
            $protokoll += "Fertig."
            
            Write-Host ""
            Write-Host "Fertig."
            Write-Host ""
            
            $meldungOrdner = "Verarbeitete Ordner: $anzahlOrdner"
            Write-Host $meldungOrdner
            $protokoll += $meldungOrdner
            
            if ($Test) {
                $meldung1 = "Anzahl Dateien, die umbenannt würden: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
                Write-Host ""
                Write-Host "Es wurden keine Dateien umbenannt."
                Write-Host "Wenn alles richtig aussieht, entferne _test aus dem Namen der Starter-Batchdatei."
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
                $protokoll += "Es wurden keine Dateien umbenannt."
            }
            else {
                $meldung1 = "Anzahl umbenannt: $anzahlUmbenannt"
                $meldung2 = "Anzahl übersprungen: $anzahlUebersprungen"
                $meldung3 = "Anzahl Fehler: $anzahlFehler"
            
                Write-Host $meldung1
                Write-Host $meldung2
                Write-Host $meldung3
            
                $protokoll += $meldung1
                $protokoll += $meldung2
                $protokoll += $meldung3
            }
            
            
            # ------------------------------------------------------------
            # Optionale Ausgabe als Logdatei und in die Zwischenablage
            # ------------------------------------------------------------
            
            $protokollText = $protokoll -join [Environment]::NewLine
            $zeitstempel = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
            $logDatei = Join-Path -Path $PSScriptRoot -ChildPath "umbenennprotokoll_ordnerinhalt_$zeitstempel.log"
            
            if ($logDateiErstellen) {
                try {
                    $protokollText | Set-Content -LiteralPath $logDatei -Encoding UTF8 -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde erstellt:"
                    Write-Host $logDatei
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht erstellt werden. Grund: $($_.Exception.Message)"
                }
            }
            
            if ($zwischenablageVerwenden) {
                try {
                    $protokollText | Set-Clipboard -ErrorAction Stop
                    Write-Host ""
                    Write-Host "Das Protokoll wurde zusätzlich in die Zwischenablage kopiert."
                }
                catch {
                    Write-Host ""
                    Write-Host "FEHLER: Das Protokoll konnte nicht in die Zwischenablage kopiert werden. Grund: $($_.Exception.Message)"
                }
            }
            
            Write-Host ""
            Read-Host "Drücke Enter zum Beenden"

            Code der SendTo-Ordnerinhalt-Datei erklärt

            Nur Ordner akzeptieren

            if (-not (Test-Path -LiteralPath $elementPfad -PathType Container)) {
                # Pfad überspringen
            }

            -PathType Container verlangt einen Ordner. Wird versehentlich eine einzelne Datei an diese Variante gesendet, wird sie kontrolliert übersprungen.

            Nur direkt enthaltene Dateien erfassen

            $dateien = @(
                Get-ChildItem -LiteralPath $ordner.FullName
                              -File
                              -Force
                              -ErrorAction Stop
            )

            -File beschränkt das Ergebnis auf Dateien. Da -Recurse nicht verwendet wird, werden Unterordner nicht durchsucht. -Force bezieht auch versteckte Dateien ein, soweit der Zugriff möglich ist.

            Mehrere Ordner protokollieren

            $anzahlOrdner++
            $protokoll += "Verarbeiteter Ordner: $($ordner.FullName)"

            Jeder erfolgreich gelesene Ordner wird gezählt und mit seinem vollständigen Pfad in das Protokoll aufgenommen.

            Pläne nach der Prüfung gemeinsam ausführen

            Auch diese Variante sammelt zunächst alle gültigen Umbenennungen in $plaene. Dadurch erscheint die Sicherheitsabfrage erst, wenn feststeht, welche Dateien tatsächlich umbenannt werden können.

            Der komplette Code der SendTo-Ordnerinhalt-Starter-Batchdatei

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            REM Script: 005_sendto_ordnerinhalt_mit_praefix_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet die SendTo-Variante für Ordnerinhalte.
            REM Autor: Chris
            REM YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            REM Webseite: https://www.toptorials.com
            REM Version: 1.0
            REM Stand: 2026-08-08
            REM
            REM Hinweis:
            REM Solange _test im Dateinamen steht, wird -Test uebergeben.
            REM Fuer die echte Ausfuehrung _test aus dem Dateinamen entfernen.
            REM ============================================================
            
            chcp 65001 >nul
            cd /d "%~dp0"
            
            echo %~n0 | find /i "_test" >nul
            
            if not errorlevel 1 (
                pwsh -ExecutionPolicy Bypass -File "005_sendto_ordnerinhalt_mit_praefix_umbenennen.ps1" -Test %*
            ) else (
                pwsh -ExecutionPolicy Bypass -File "005_sendto_ordnerinhalt_mit_praefix_umbenennen.ps1" %*
            )

            Code der SendTo-Starter-Batchdateien erklärt

            Der entscheidende Unterschied zur einfachen Starterdatei ist %*:

            pwsh -ExecutionPolicy Bypass -File "005_sendto_elemente_mit_praefix_umbenennen.ps1" -Test %*

            %* enthält alle Argumente, die Windows an die Batchdatei übergeben hat. Dadurch erhält PowerShell sämtliche im Explorer markierten Pfade.

            %* wird nicht zusätzlich als "%*" geschrieben. Andernfalls könnten mehrere getrennte Pfade zu einem einzigen Argument zusammengefasst werden.

            SendTo-Verknüpfungen einrichten

            Den SendTo-Ordner von Windows öffnen:

            Windows-Taste + R
            shell:sendto
            Enter

            In diesem Ordner werden Verknüpfungen zu den beiden SendTo-Starterdateien angelegt:

            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs\005_Dateien_mit_Praefix_umbenennen\03_SendTo_Elemente_umbenennen\005_sendto_elemente_mit_praefix_umbenennen_starter_batch_test.bat
            
            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs\005_Dateien_mit_Praefix_umbenennen\04_SendTo_Ordnerinhalt_umbenennen\005_sendto_ordnerinhalt_mit_praefix_umbenennen_starter_batch_test.bat

            Die Verknüpfungen können zum Beispiel so heißen:

            Elemente mit Präfix umbenennen - TEST
            Ordnerinhalt mit Präfix umbenennen - TEST

            Danach stehen sie im Explorer unter Rechtsklick – Senden an zur Verfügung.

            Wird _test später aus dem Namen der jeweiligen Starter-Batchdatei entfernt, muss die zugehörige Verknüpfung gegebenenfalls aktualisiert oder neu erstellt werden.

            Logdateien und Zwischenablage

            Die einfache Variante speichert ihre Logdatei im verarbeiteten Ordner:

            umbenennprotokoll_2026-08-10_14-30-25.log

            Die beiden SendTo-Varianten speichern Logdateien im jeweiligen Skriptordner:

            umbenennprotokoll_elemente_2026-08-10_14-30-25.log
            umbenennprotokoll_ordnerinhalt_2026-08-10_14-30-25.log

            Dafür verwenden sie $PSScriptRoot. Diese automatische Variable enthält den vollständigen Ordnerpfad des ausgeführten PowerShell-Skripts – unabhängig davon, welche Elemente über SendTo verarbeitet werden.

            Der Protokolltext wird so zusammengesetzt:

            $protokollText = $protokoll -join [Environment]::NewLine

            -join verbindet alle Einträge des Arrays. [Environment]::NewLine setzt zwischen die Einträge passende Zeilenumbrüche.

            Typische Meldungen

            WÜRDE UMBENENNEN

            Das Element würde bei der echten Ausführung den angezeigten neuen Namen erhalten. Im Testmodus wird nichts verändert.

            UMBENANNT

            Das Element wurde im Echtmodus erfolgreich umbenannt.

            ÜBERSPRUNGEN

            Das Element wurde nicht verändert. Mögliche Gründe sind ein bereits vorhandenes Präfix, ein existierendes Ziel, ein geschütztes Skript, ein nicht gefundener Pfad oder eine für die Variante ungeeignete Eingabe.

            FEHLER

            Ein Element konnte nicht gelesen oder umbenannt, eine Logdatei nicht geschrieben oder der Protokolltext nicht in die Zwischenablage kopiert werden.

            Typische Fehler und Lösungen

            PowerShell 7 wurde nicht gefunden

            Die Starterdateien verwenden pwsh. Prüfe mit pwsh --version, ob PowerShell 7 installiert und über die Umgebungsvariable PATH erreichbar ist.

            Die PowerShell-Datei wurde nicht gefunden

            Die PowerShell-Datei und die zugehörige Starter-Batchdatei müssen gemeinsam im gleichen Ordner liegen. Die Dateinamen im Batchcode müssen exakt mit den tatsächlichen Dateinamen übereinstimmen.

            Die SendTo-Datei wurde direkt gestartet

            Beim Doppelklick wurden keine Datei- oder Ordnerpfade übergeben. Die SendTo-Varianten sollten über Rechtsklick – Senden an gestartet werden.

            Eine Datei wurde bei der Ordnerinhalt-Variante übersprungen

            Diese Variante erwartet ausschließlich Ordner. Um eine einzelne Datei direkt umzubenennen, wird die SendTo-Elemente-Variante verwendet.

            Ein Ordnerinhalt wurde nicht verarbeitet

            Die SendTo-Elemente-Variante benennt einen ausgewählten Ordner selbst um. Für seine direkt enthaltenen Dateien ist die SendTo-Ordnerinhalt-Variante vorgesehen.

            Dateien in Unterordnern wurden nicht umbenannt

            Das ist beabsichtigt. Die Ordnerinhalt-Variante arbeitet nicht rekursiv und verarbeitet nur Dateien direkt in den übergebenen Ordnern.

            Eine Datei wurde wegen eines vorhandenen Ziels übersprungen

            Im selben Ordner existiert bereits ein Element mit dem geplanten neuen Namen. Das vorhandene Ziel wird nicht überschrieben.

            Eine Datei erhielt beim zweiten Lauf ein weiteres Präfix

            Das Skript erkennt nur das Präfix, das beim aktuellen Lauf eingestellt oder erzeugt wurde. Ein täglich wechselndes Datum oder eine aktuelle Uhrzeit unterscheidet sich von einem früheren Präfix und kann deshalb erneut ergänzt werden.

            Das Präfix wird als ungültig gemeldet

            Prüfe, ob es leer ist, nur aus Leerzeichen besteht oder ein unter Windows unzulässiges Dateinamenzeichen enthält.

            Keine Logdatei wurde erstellt

            Die Logausgabe ist standardmäßig ausgeschaltet. Aktiviere eine der vorbereiteten Varianten mit $logDateiErstellen = $true.

            Die Eingabe ja wurde nicht akzeptiert

            In dieser Version muss für den Echtmodus exakt JA in Großbuchstaben eingegeben werden.

            Umlaute oder Sonderzeichen werden falsch angezeigt

            Die Starter-Batchdatei stellt die Konsole mit chcp 65001 auf UTF-8 um. Prüfe außerdem, ob die PowerShell- und Batchdateien als UTF-8 gespeichert wurden.

            Nützliche PowerShell-Begriffe aus diesem Teil

            param
            Definiert Parameter, die beim Start an ein Skript übergeben werden können.
            
            [switch]
            Definiert einen Schalter, der vorhanden oder nicht vorhanden ist.
            
            [string[]]
            Definiert ein Array aus Textwerten.
            
            Get-Date
            Liefert Datum und Uhrzeit und kann beide Werte formatieren.
            
            Get-Location
            Liefert den aktuellen Arbeitsordner.
            
            Get-Item
            Liest ein bestimmtes Datei- oder Ordnerobjekt.
            
            Get-ChildItem
            Liest Inhalte eines Ordners aus.
            
            Test-Path
            Prüft, ob ein Pfad existiert und optional, ob er eine Datei oder einen Ordner bezeichnet.
            
            Split-Path
            Gibt einen bestimmten Bestandteil eines Pfades zurück, hier den Elternpfad.
            
            Join-Path
            Verbindet Pfadbestandteile zu einem vollständigen Pfad.
            
            Rename-Item
            Benennt eine Datei oder einen Ordner um.
            
            -LiteralPath
            Behandelt den übergebenen Pfad wörtlich und nicht als Platzhaltermuster.
            
            -ErrorAction Stop
            Leitet einen Fehler an den zugehörigen catch-Block weiter.
            
            StartsWith()
            Prüft, ob ein Text mit einem bestimmten Text beginnt.
            
            IndexOfAny()
            Sucht nach einem von mehreren Zeichen und liefert dessen Position.
            
            OrdinalIgnoreCase
            Vergleicht technischen Text ohne Beachtung der Groß- und Kleinschreibung.
            
            Select-Object -Unique
            Entfernt identische Mehrfacheinträge.
            
            Sort-Object
            Sortiert Objekte nach einem angegebenen Wert.
            
            [PSCustomObject]
            Erstellt ein eigenes Objekt mit benannten Eigenschaften.
            
            $PSScriptRoot
            Enthält den vollständigen Ordnerpfad des ausgeführten PowerShell-Skripts.
            
            $PSCommandPath
            Enthält den vollständigen Pfad der ausgeführten PowerShell-Datei.
            
            try / catch
            Fängt erwartbare Fehler kontrolliert ab.
            
            $_
            Steht im catch-Block für das aktuelle Fehlerobjekt.
            
            $_.Exception.Message
            Liefert den lesbaren Text der Fehlermeldung.
            
            continue
            Springt zum nächsten Durchlauf einer Schleife.
            
            $true / $false
            Boolesche Wahrheitswerte.

            Wichtige Batch-Begriffe aus diesem Teil

            @echo off
            Blendet die ausgeführten Batchbefehle aus.
            
            chcp 65001
            Stellt die Konsole auf UTF-8 um.
            
            >nul
            Unterdrückt eine Befehlsausgabe.
            
            cd /d
            Wechselt Ordner und bei Bedarf Laufwerk.
            
            %~dp0
            Laufwerk und Ordner der gestarteten Batchdatei.
            
            %~n0
            Name der gestarteten Batchdatei ohne Dateiendung.
            
            find /i
            Sucht unabhängig von Groß- und Kleinschreibung.
            
            errorlevel
            Enthält den Rückgabestatus des vorherigen Befehls.
            
            pwsh
            Startet PowerShell 7.
            
            %*
            Enthält alle an die Batchdatei übergebenen Argumente.

            Was haben wir gelernt?

            den Testmodus mit einem Switch-Parameter steuern
            Datum und Uhrzeit mit Get-Date formatieren
            ein eigenes Präfix festlegen
            ungültige Dateinamenzeichen erkennen
            Dateien und Ordner über SendTo an PowerShell übergeben
            doppelte Pfadangaben entfernen
            den Elternpfad mit Split-Path ermitteln
            Pfade mit Join-Path zusammensetzen
            bereits vorhandene Präfixe mit StartsWith() erkennen
            Groß- und Kleinschreibung kontrolliert ignorieren
            vorhandene Ziele mit Test-Path schützen
            Umbenennungen mit PSCustomObject planen
            verschachtelte Elemente nach Pfadlänge sortieren
            Dateien und Ordner mit Rename-Item umbenennen
            nur direkt enthaltene Dateien eines Ordners erfassen
            Fehler mit try und catch behandeln
            Meldungen und Statistiken in einem Protokoll sammeln
            Logdateien mit Set-Content schreiben
            Text mit Set-Clipboard in die Zwischenablage kopieren
            den Skriptordner mit $PSScriptRoot ermitteln
            mehrere Batchargumente mit %* weitergeben

            Video zu diesem Tutorial:

             

            Das könnte Dich auch interessieren

            Keine Einträge gefunden

            Schreibe einen Kommentar Antwort abbrechen

            Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

            INTERESSANTE SEITEN

            • TUTORIALS SCHNELLER FINDEN
            • SCHNELLER RECHNEN LERNEN
            • MATHE AUFGABEN GENERATOR
            • LINIEN UND KARO GENERATOR
            • VORLAGEN ZUM AUSDRUCKEN
            • BINGO-SCHEIN-GENERATOR
            • MEINE WUNSCHLISTE
            • Symbole zum Kopieren

            Content

            • Microsoft Excel Tutorials
            • Microsoft Excel VBA Tutorials
            • Microsoft Word Tutorials
            • Microsoft Powerpoint Tutorials
            • Microsoft Windows 10 Tutorials
            • Google Tabellen Tutorials
            • Google Tabellen Script Tutorials
            • Google Docs Tutorials
            • LibreOffice Calc Tutorials
            • Libre Office Writer Tutorials
            • LibreOffice Impress Tutorials
            • OpenOffice Calc Tutorials
            • OpenOffice Writer Tutorials
            • OpenOffice Impress Tutorials
            • WPS Spreadsheets Tutorials
            • WPS Spreadsheets Tutorials

            Neue Beiträge

            • PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen
            • Batch Grundkurs 005: Dateien mit Präfix umbenennen
            • Python Grundkurs 004: Dateien automatisch nach Dateityp sortieren
            • PowerShell 7 Grundkurs 004: Dateien automatisch nach Dateityp sortieren
            • Batch Grundkurs 004: Dateien nach Dateityp automatisch sortieren

            Neue Kommentare

            • Chris zu Python in LibreOffice Calc: Formular auslesen und auswerten
            • Detlef M. zu Python in LibreOffice Calc: Formular auslesen und auswerten
            • Johannes Hanel zu Verknüpfungen in LibreOffice Calc
            • Holfrie zu Symbole vergrößern von der Benutzeroberfläche (OpenOffice)
            • Bianca zu Tutorial Wunsch Liste
            • Wolfgang Dehmer zu Funktion zeitlich gesteuert ausführen (Google Tabellen) Script

            Schlagwörter-Wolke

            anfänger Anleitung anpassen ausrechnen auswahlliste Bedingte Formatierung berechnen Calc Datum Download Dropdownliste einfügen entfernen erstellen Excel FreeOffice Funktion google hinzufügen Jahresplan Kalender Lernvideo LibreOffice löschen Makro markieren Microsoft OpenOffice PlanMaker programmierung script spreadsheets Sverweis Tabelle tabellen Tutorial VBA Video Wenn Wenn Funktion Word wps spreadsheets Zeilen Zelle Zellen
            KONTAKT   IMPRESSUM    DATENSCHUTZERKLÄRUNG    HAFTUNGSAUSSCHLUSS (Disclaimer)   © copyright TOPTORIALS