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

            PowerShell 7 Grundkurs Teil 006: Ordnername als Präfix

            • Startseite
            • Tutorials Windows Automatisierung Powershell 7 Grundkurs
            • PowerShell 7 Grundkurs Teil 006: Ordnername als Präfix

            PowerShell 7 Grundkurs Teil 006: Ordnername als Präfix

            Worum geht es in diesem Teil?

            In diesem Teil des PowerShell-7-Grundkurses verwenden wir den Namen eines Ordners automatisch als Präfix für die direkt darin enthaltenen Dateien.

            Aus diesen Dateien:

            Rechnungen\beleg001.pdf
            Rechnungen\beleg002.pdf

            werden beispielsweise:

            Rechnungen\Rechnungen_beleg001.pdf
            Rechnungen\Rechnungen_beleg002.pdf
            
            oder
            Ordner-Ausgaben

            Ordner-Ausgaben

            Ordner-Ausgaben

            Ordner-Ausgaben

            Der Ordnername bleibt dabei unverändert. Auch mögliche Unterordner werden nicht umbenannt und nicht rekursiv durchsucht.

            Wir erstellen zwei Varianten:

            • Die erste Variante verarbeitet den Inhalt aller direkten Unterordner eines festgelegten Hauptordners.
            • Die zweite Variante wird über das Windows-Menü Senden an gestartet und verarbeitet die direkt enthaltenen Dateien der ausgewählten Ordner.

            Was ist das Ziel?

            Die Skripte sollen Dateien übersichtlich und sicher umbenennen. Der jeweilige Ordnername wird zusammen mit einem Unterstrich vor den bisherigen Dateinamen gesetzt.

            Bereits passend benannte Dateien werden übersprungen. Existiert der geplante Zielname bereits, findet ebenfalls keine Umbenennung statt. Vor dem Echtlauf kann der vollständige Ablauf im Testmodus geprüft werden.

            Warum ist dieser Teil wichtig?

            In diesem Tutorial verbinden wir mehrere wichtige Grundlagen aus PowerShell 7:

            • Get-ChildItem -Directory ermittelt die direkten Unterordner.
            • Get-ChildItem -File ermittelt nur die direkt enthaltenen Dateien.
            • $ordner.Name liefert den Namen, der als Präfix verwendet wird.
            • Join-Path setzt Ordnerpfad und neuen Dateinamen sicher zusammen.
            • StartsWith erkennt ein bereits vorhandenes Präfix ohne Beachtung der Groß- und Kleinschreibung.
            • Test-Path schützt bereits vorhandene Zieldateien.
            • [PSCustomObject] speichert die geplanten Umbenennungen mit Quelle und Ziel.
            • Rename-Item führt die eigentliche Umbenennung erst nach der Prüfung aus.
            • try und catch fangen typische Datei- und Ordnerfehler kontrolliert ab.

            Hinweis zur Kursreihe

            Dieses Tutorial gehört zum PowerShell-7-Grundkurs. Der Aufbau orientiert sich an den entsprechenden Teilen für Batch und Python. Dadurch lassen sich die unterschiedlichen Schreibweisen und Möglichkeiten der drei Programmiersprachen besonders gut vergleichen.

            Downloads zu diesem Teil

            Dateien für PowerShell 7 Grundkurs Teil 006:
            Download PowerShell 7 Grundkurs: 006_Ordnername_als_Praefix als ZIP-Datei.Entpacken nach:

            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs

            Dadurch entsteht dieser Hauptordner:

            C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs\006_Ordnername_als_Praefix

            Testumgebung zum Mitmachen

            Für gefahrlose Tests kann wieder die vorbereitete Testumgebung verwendet werden.

            Testumgebung für Windows-Automatisierung:Download TOPTORIALS_Testdaten_Windows_Automatisierung_V001.zip

            Entpacken nach:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH

            Für PowerShell 7 befindet sich der passende Testbereich anschließend unter:

            C:\TOPTORIALS_CODE\1000_TESTBEREICH\TOPTORIALS_Testdaten_Windows_Automatisierung_PowerShell_7_V001\006_Ordnername_als_Praefix

            Sicherheitshinweis

            Wichtig:Teste Skripte zum Umbenennen zuerst immer mit Kopien unwichtiger Dateien. Die mitgelieferten Starter-Batchdateien enthalten im Dateinamen zunächst _test. Dadurch wird nur angezeigt und protokolliert, was das Skript umbenennen würde.

            Für den Echtmodus wird _test aus dem Namen der Starter-Batchdatei entfernt. Zusätzlich muss die Sicherheitsabfrage mit JA bestätigt werden.

            Enthaltene Ordner und Dateien

            006_Ordnername_als_Praefix
            │
            ├── 01_Unterordnerinhalt_mit_Ordnername_umbenennen
            │   ├── 006_unterordnerinhalt_mit_ordnername_umbenennen.ps1
            │   └── 006_unterordnerinhalt_mit_ordnername_umbenennen_starter_batch_test.bat
            │
            └── 02_SendTo_Ordnerinhalt_mit_Ordnername_umbenennen
                ├── 006_sendto_ordnerinhalt_mit_ordnername_umbenennen.ps1
                └── 006_sendto_ordnerinhalt_mit_ordnername_umbenennen_starter_batch_test.bat

            Wie wird das Präfix gebildet?

            Der Name des gerade verarbeiteten Ordners wird mit einem Unterstrich verbunden:

            $praefix = $ordner.Name + "_"

            Heißt der Ordner beispielsweise Rechnungen, lautet das Präfix Rechnungen_.

            Der neue Dateiname entsteht anschließend aus Präfix und bisherigem Dateinamen:

            $neuerName = $praefix + $datei.Name

            Testmodus und Echtmodus

            Die Starter-Batchdatei erkennt am eigenen Dateinamen, ob _test enthalten ist.

            • Mit _test wird PowerShell 7 mit dem Schalter -Test aufgerufen.
            • Ohne _test startet das Skript im Echtmodus.

            Die PowerShell-Skripte sammeln zuerst alle gültigen Umbenennungen in einer Liste mit Plänen. Erst danach werden die Pläne entweder nur ausgegeben oder wirklich ausgeführt.

            Ausgabe und Protokoll

            Nach dem Prüfen der Dateien kann die Ausgabe an verschiedene Ziele gesendet werden:

            • nur auf den Bildschirm,
            • nur in eine Protokolldatei,
            • nur in die Windows-Zwischenablage oder
            • gleichzeitig an alle drei Ziele.

            Sehr lange Pfade werden bei geplanten und ausgeführten Umbenennungen auf mehrere Zeilen verteilt:

            WÜRDE UMBENENNEN:
            Quelle: "C:\...\Rechnungen\beleg001.pdf"
            Ziel:   "C:\...\Rechnungen\Rechnungen_beleg001.pdf"
            ---

            Innerhalb eines PowerShell-Textes erzeugt `n den Zeilenumbruch. Dadurch bleiben auch lange Quell- und Zielpfade gut lesbar.

            Variante 1: Inhalte der direkten Unterordner umbenennen

            Bei dieser Variante liegen das PowerShell-Skript und die Starter-Batchdatei gemeinsam in einem Hauptordner. Das Skript sucht darin alle direkten Unterordner und verarbeitet jeweils die direkt enthaltenen Dateien.

            Eine mögliche Ausgangssituation sieht so aus:

            01_Unterordnerinhalt_mit_Ordnername_umbenennen
            │
            ├── Rechnungen
            │   ├── beleg001.pdf
            │   └── beleg002.pdf
            │
            └── Scans
                ├── dokument001.jpg
                └── dokument002.jpg

            Im Testmodus würde das Skript unter anderem folgende Ziele planen:

            Rechnungen\Rechnungen_beleg001.pdf
            Rechnungen\Rechnungen_beleg002.pdf
            Scans\Scans_dokument001.jpg
            Scans\Scans_dokument002.jpg

            Vollständiges PowerShell-7-Skript

            # ============================================================
            # TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            # Script: 006_unterordnerinhalt_mit_ordnername_umbenennen.ps1
            # Beschreibung: Benennt Dateien in Unterordnern mit dem jeweiligen Ordnernamen als Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-14
            # ============================================================
            
            param (
                [switch]$Test
            )
            
            Write-Host ""
            
            $basisOrdner = (Get-Location).Path
            
            
            # ------------------------------------------------------------
            # 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
            
            
            # ------------------------------------------------------------
            # Modus, Zähler und Protokoll vorbereiten
            # ------------------------------------------------------------
            
            if ($Test) {
                $modusText = "TESTMODUS"
            }
            else {
                $modusText = "ECHTMODUS"
            }
            
            $anzahlUmbenannt = 0
            $anzahlUebersprungen = 0
            $anzahlFehler = 0
            $anzahlOrdner = 0
            $protokoll = @()
            $plaene = @()
            
            $protokoll += "Dateien in Unterordnern werden mit dem jeweiligen Ordnernamen als Präfix umbenannt."
            $protokoll += "Modus: $modusText"
            $protokoll += "Hauptordner: $basisOrdner"
            $protokoll += ""
            
            Write-Host "Dateien in Unterordnern werden mit dem jeweiligen Ordnernamen als Präfix umbenannt..."
            Write-Host ""
            Write-Host "Hauptordner:"
            Write-Host $basisOrdner
            Write-Host ""
            Write-Host "Modus: $modusText"
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Direkt enthaltene Unterordner erfassen
            # Tiefere Unterordner werden nicht durchsucht.
            # ------------------------------------------------------------
            
            try {
                $unterordner = @(Get-ChildItem -LiteralPath $basisOrdner -Directory -Force -ErrorAction Stop)
            }
            catch {
                Write-Host "FEHLER: Die Unterordner konnten nicht gelesen werden. Grund: $($_.Exception.Message)"
                Write-Host ""
                Read-Host "Drücke Enter zum Beenden"
                exit
            }
            
            
            # ------------------------------------------------------------
            # Dateien prüfen und Umbenennungen planen
            # ------------------------------------------------------------
            
            foreach ($ordner in $unterordner) {
                $praefix = $ordner.Name + "_"
            
                try {
                    $dateien = @(Get-ChildItem -LiteralPath $ordner.FullName -File -Force -ErrorAction Stop)
                    $anzahlOrdner++
            
                    Write-Host "Ordner wird verarbeitet:"
                    Write-Host $ordner.FullName
                    Write-Host "Präfix: $praefix"
                    Write-Host ""
            
                    $protokoll += "Verarbeiteter Ordner: $($ordner.FullName)"
                    $protokoll += "Präfix: $praefix"
                }
                catch {
                    $meldung = "FEHLER: Ordnerinhalt konnte nicht gelesen werden: `"$($ordner.FullName)`". Grund: $($_.Exception.Message)"
                    Write-Host $meldung
                    Write-Host ""
                    $protokoll += $meldung
                    $protokoll += ""
                    $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]@{
                        Ordner    = $ordner.FullName
                        Praefix   = $praefix
                        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 Unterordnern 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 ""
            }
            
            
            # ------------------------------------------------------------
            # Geplante Umbenennungen ausführen
            # ------------------------------------------------------------
            
            foreach ($plan in $plaene) {
                if ($Test) {
                    $meldung = "WÜRDE UMBENENNEN:`nQuelle: `"$($plan.Quelle)`"`nZiel:   `"$($plan.Ziel)`"`n---"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                    continue
                }
            
                try {
                    Rename-Item -LiteralPath $plan.Quelle -NewName $plan.NeuerName -ErrorAction Stop
            
                    $meldung = "UMBENANNT:`nQuelle: `"$($plan.Quelle)`"`nZiel:   `"$($plan.Ziel)`"`n---"
                    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 Unterordner: $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 $basisOrdner -ChildPath "umbenennprotokoll_unterordnerinhalt_$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"

            So funktioniert die erste Variante

            $PSScriptRoot liefert den Ordner, in dem das PowerShell-Skript gespeichert ist. Dieser Ordner wird als Ausgangspunkt verwendet.

            $basisOrdner = $PSScriptRoot

            Mit Get-ChildItem -Directory werden nur die direkten Unterordner ermittelt:

            $unterordner = @(Get-ChildItem -LiteralPath $basisOrdner -Directory -ErrorAction Stop)

            Für jeden dieser Ordner wird anschließend ein eigenes Präfix gebildet. Get-ChildItem -File übernimmt nur die unmittelbar darin liegenden Dateien. Unterordner werden nicht rekursiv durchsucht.

            Die Prüfung mit StartsWith verwendet [System.StringComparison]::OrdinalIgnoreCase. Dadurch werden Groß- und Kleinschreibung beim Erkennen des Präfixes nicht unterschieden.

            Jede gültige Umbenennung wird zuerst als [PSCustomObject] mit Quelle und Ziel in $plaene gespeichert:

            $plaene += [PSCustomObject]@{
                Quelle = $datei.FullName
                Ziel   = $zielPfad
            }

            Im Testmodus werden diese Pläne lediglich angezeigt. Im Echtmodus erfolgt zuerst die zusätzliche Bestätigung mit JA. Erst danach ruft die zweite Schleife Rename-Item auf.

            Starter-Batchdatei für Variante 1

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            REM Script: 006_unterordnerinhalt_mit_ordnername_umbenennen_starter_batch_test.bat
            REM Beschreibung: Startet die Variante für Unterordnerinhalte.
            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-14
            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 "006_unterordnerinhalt_mit_ordnername_umbenennen.ps1" -Test
            ) else (
                pwsh -ExecutionPolicy Bypass -File "006_unterordnerinhalt_mit_ordnername_umbenennen.ps1"
            )

            %~dp0 liefert den Ordner der Starter-Batchdatei. Dadurch kann sie das PowerShell-Skript unabhängig vom aktuell geöffneten Konsolenordner finden.

            pwsh.exe startet ausdrücklich PowerShell 7. Die Option -NoProfile verhindert, dass ein persönliches PowerShell-Profil das Verhalten beeinflusst. Mit -File wird das angegebene Skript ausgeführt.

            Variante 2: Ausgewählte Ordner über „Senden an“ verarbeiten

            Die zweite Variante eignet sich für das Kontextmenü des Windows-Explorers. Dort können ein oder mehrere Ordner markiert und über Senden an an die Starter-Batchdatei übergeben werden.

            Das Skript benennt nur die direkt enthaltenen Dateien der übergebenen Ordner um. Die ausgewählten Ordner selbst bleiben unverändert. Auch Unterordner und deren Inhalte werden nicht verarbeitet.

            Vollständiges PowerShell-7-Skript

            # ============================================================
            # TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            # Script: 006_sendto_ordnerinhalt_mit_ordnername_umbenennen.ps1
            # Beschreibung: Benennt Dateien in über SendTo übergebenen Ordnern mit dem jeweiligen Ordnernamen als Präfix um.
            # Autor: Chris
            # YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
            # Webseite: https://www.toptorials.com
            # Version: 1.0
            # Stand: 2026-08-14
            # ============================================================
            
            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
            }
            
            
            # ------------------------------------------------------------
            # 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
            
            
            # ------------------------------------------------------------
            # Modus, Zähler und Protokoll vorbereiten
            # ------------------------------------------------------------
            
            if ($Test) {
                $modusText = "TESTMODUS"
            }
            else {
                $modusText = "ECHTMODUS"
            }
            
            $anzahlUmbenannt = 0
            $anzahlUebersprungen = 0
            $anzahlFehler = 0
            $anzahlOrdner = 0
            $protokoll = @()
            $plaene = @()
            
            $protokoll += "Dateien in übergebenen Ordnern werden mit dem jeweiligen Ordnernamen als Präfix umbenannt."
            $protokoll += "Modus: $modusText"
            $protokoll += ""
            
            Write-Host "Dateien in übergebenen Ordnern werden mit dem jeweiligen Ordnernamen als Präfix umbenannt..."
            Write-Host ""
            Write-Host "Modus: $modusText"
            Write-Host ""
            
            
            # ------------------------------------------------------------
            # Übergebene 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
            
                    if ($null -eq $ordner.Parent) {
                        $meldung = "ÜBERSPRUNGEN: Eine Laufwerkswurzel wird aus Sicherheitsgründen nicht verarbeitet: `"$($ordner.FullName)`""
                        Write-Host $meldung
                        $protokoll += $meldung
                        $anzahlUebersprungen++
                        continue
                    }
            
                    $praefix = $ordner.Name + "_"
                    $dateien = @(Get-ChildItem -LiteralPath $ordner.FullName -File -Force -ErrorAction Stop)
                    $anzahlOrdner++
            
                    Write-Host "Ordner wird verarbeitet:"
                    Write-Host $ordner.FullName
                    Write-Host "Präfix: $praefix"
                    Write-Host ""
            
                    $protokoll += "Verarbeiteter Ordner: $($ordner.FullName)"
                    $protokoll += "Präfix: $praefix"
                }
                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]@{
                        Ordner    = $ordner.FullName
                        Praefix   = $praefix
                        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 ""
            }
            
            
            # ------------------------------------------------------------
            # Geplante Umbenennungen ausführen
            # ------------------------------------------------------------
            
            foreach ($plan in $plaene) {
                if ($Test) {
                    $meldung = "WÜRDE UMBENENNEN:`nQuelle: `"$($plan.Quelle)`"`nZiel:   `"$($plan.Ziel)`"`n---"
                    Write-Host $meldung
                    $protokoll += $meldung
                    $anzahlUmbenannt++
                    continue
                }
            
                try {
                    Rename-Item -LiteralPath $plan.Quelle -NewName $plan.NeuerName -ErrorAction Stop
            
                    $meldung = "UMBENANNT:`nQuelle: `"$($plan.Quelle)`"`nZiel:   `"$($plan.Ziel)`"`n---"
                    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_sendto_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"

            So funktioniert die SendTo-Variante

            Der Parameterblock nimmt alle vom Explorer übergebenen Pfade entgegen:

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

            [string[]] bedeutet, dass $Elemente mehrere Texte und damit mehrere Pfade enthalten kann. ValueFromRemainingArguments sorgt dafür, dass alle übrigen Argumente in dieser Liste gesammelt werden.

            Select-Object -Unique entfernt doppelt übergebene Pfade. Danach prüft das Skript jeden Pfad einzeln. Dateien, nicht vorhandene Pfade und Laufwerkswurzeln werden aus Sicherheitsgründen nicht verarbeitet.

            Für jeden gültigen Ordner wird dessen eigener Name als Präfix verwendet. Werden beispielsweise die Ordner Rechnungen und Scans gemeinsam ausgewählt, erhalten die Dateien jeweils das passende Präfix ihres eigenen Ordners.

            Starter-Batchdatei für die SendTo-Variante

            @echo off
            REM ============================================================
            REM TOPTORIALS OFFICE - PowerShell 7 Grundkurs
            REM Script: 006_sendto_ordnerinhalt_mit_ordnername_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-14
            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 "006_sendto_ordnerinhalt_mit_ordnername_umbenennen.ps1" -Test %*
            ) else (
                pwsh -ExecutionPolicy Bypass -File "006_sendto_ordnerinhalt_mit_ordnername_umbenennen.ps1" %*
            )

            %* übergibt alle im Explorer markierten Ordner an das PowerShell-Skript. Anführungszeichen um die einzelnen vom Explorer gelieferten Argumente bleiben dabei erhalten, sodass auch Pfade mit Leerzeichen verarbeitet werden können.

            SendTo-Verknüpfung einrichten

            1. Mit Windows + R den Dialog Ausführen öffnen.
            2. shell:sendto eingeben und mit Enter bestätigen.
            3. Eine Verknüpfung zur Starter-Batchdatei in diesem Ordner anlegen.
            4. Der Verknüpfung einen verständlichen Namen geben, zum Beispiel Ordnerinhalt mit Ordnername als Präfix - TEST.

            Danach können die gewünschten Ordner im Explorer markiert und über Rechtsklick → Senden an verarbeitet werden.

            Wo werden die Protokolle gespeichert?

            Die erste Variante speichert ihre Protokolle im gemeinsamen Hauptordner des Skripts. Auch die SendTo-Variante verwendet den Ordner, in dem ihr PowerShell-Skript liegt.

            Die Dateinamen enthalten Datum und Uhrzeit, zum Beispiel:

            006_unterordnerinhalt_mit_ordnername_umbenennen_TEST_20260815_153045.log
            006_sendto_ordnerinhalt_mit_ordnername_umbenennen_20260815_153210.log

            Dadurch überschreibt ein neuer Durchlauf kein älteres Protokoll.

            Typische Meldungen

            Datei würde umbenannt

            WÜRDE UMBENENNEN:
            Quelle: "C:\Daten\Rechnungen\beleg001.pdf"
            Ziel:   "C:\Daten\Rechnungen\Rechnungen_beleg001.pdf"
            ---

            Datei wurde umbenannt

            UMBENANNT:
            Quelle: "C:\Daten\Rechnungen\beleg001.pdf"
            Ziel:   "C:\Daten\Rechnungen\Rechnungen_beleg001.pdf"
            ---

            Präfix ist bereits vorhanden

            ÜBERSPRUNGEN: "C:\Daten\Rechnungen\Rechnungen_beleg001.pdf" - Präfix ist bereits am Anfang enthalten

            Zieldatei existiert bereits

            ÜBERSPRUNGEN: "C:\Daten\Rechnungen\beleg001.pdf" - Zieldatei existiert bereits: "C:\Daten\Rechnungen\Rechnungen_beleg001.pdf"

            Typische Fehler und mögliche Ursachen

            PowerShell 7 wurde nicht gefunden

            Die Starter-Batchdateien verwenden pwsh.exe. Ist PowerShell 7 nicht installiert oder nicht über die Umgebungsvariable PATH erreichbar, kann das Skript nicht gestartet werden.

            Das Skript wird nicht gefunden

            PowerShell-Skript und passende Starter-Batchdatei müssen gemeinsam im vorgesehenen Ordner liegen. Auch die Dateinamen müssen unverändert zueinander passen.

            Es werden keine Dateien gefunden

            Die Skripte verarbeiten ausschließlich direkt enthaltene Dateien. Liegen die Dateien erst in einer weiteren Unterordnerebene, werden sie absichtlich nicht erfasst.

            Ein ausgewähltes Element wird übersprungen

            Die SendTo-Variante erwartet Ordner. Einzelne Dateien und Laufwerkswurzeln werden bewusst nicht verarbeitet.

            Eine Datei kann nicht umbenannt werden

            Mögliche Ursachen sind fehlende Zugriffsrechte, eine in einem anderen Programm geöffnete Datei, ein schreibgeschützter Datenträger oder ein bereits vorhandenes Ziel.

            Wichtige PowerShell-Begriffe aus diesem Tutorial

            $PSScriptRoot
            Liefert den Ordner, in dem das aktuell ausgeführte PowerShell-Skript gespeichert ist.
            Get-ChildItem
            Ermittelt Dateien und Ordner. Mit -Directory werden nur Ordner und mit -File nur Dateien übernommen.
            -LiteralPath
            Behandelt den übergebenen Pfad wörtlich. Zeichen wie eckige Klammern werden dadurch nicht als Platzhalter interpretiert.
            @(...)
            Sorgt dafür, dass das Ergebnis als Array behandelt wird, auch wenn nur ein oder kein Element gefunden wurde.
            StartsWith
            Prüft, ob ein Text mit einem bestimmten Inhalt beginnt.
            [System.StringComparison]::OrdinalIgnoreCase
            Vergleicht Texte ohne Beachtung der Groß- und Kleinschreibung und ohne sprachabhängige Umwandlung.
            Join-Path
            Setzt einen Ordnerpfad und einen weiteren Pfadbestandteil korrekt zusammen.
            Test-Path
            Prüft, ob eine Datei oder ein Ordner bereits existiert.
            [PSCustomObject]
            Erstellt ein übersichtliches Objekt mit selbst gewählten Eigenschaften. Hier speichert es Quelle und Ziel eines Plans.
            Rename-Item
            Benennt eine Datei oder einen Ordner um.
            try und catch
            Fangen auftretende Fehler kontrolliert ab und ermöglichen verständliche Fehlermeldungen.
            Set-Clipboard
            Kopiert die gesammelte Ausgabe in die Windows-Zwischenablage.
            `n
            Erzeugt innerhalb eines PowerShell-Textes einen Zeilenumbruch.

            Wichtige Batch-Begriffe aus diesem Tutorial

            %~dp0
            Liefert Laufwerk und Ordner der aktuell ausgeführten Batchdatei.
            %~n0
            Liefert den Dateinamen der Batchdatei ohne Pfad und Dateiendung.
            %*
            Enthält alle Argumente, die an die Batchdatei übergeben wurden.
            findstr
            Sucht nach Text. Hier wird damit geprüft, ob der Name der Starter-Batchdatei _test enthält.
            errorlevel
            Enthält den Rückgabewert des zuletzt ausgeführten Programms oder Befehls.

            Was haben wir in diesem Teil gelernt?

            Mit $ordner.Name lässt sich der Name eines Ordners automatisch als Präfix verwenden.

            Get-ChildItem -Directory ermittelt direkte Unterordner, während Get-ChildItem -File nur die direkt enthaltenen Dateien übernimmt.

            Mit StartsWith erkennen wir ein bereits vorhandenes Präfix, und Test-Path schützt vorhandene Zieldateien.

            Die Umbenennungen werden zuerst als Pläne mit Quelle und Ziel gesammelt. Dadurch lassen sich alle Prüfungen abschließen, bevor Rename-Item im Echtmodus Änderungen vornimmt.

            Die erste Variante verarbeitet die direkten Unterordner eines festen Hauptordners. Die zweite Variante übernimmt ausgewählte Ordner über das Windows-Menü Senden an.

            Die Starter-Batchdateien starten ausdrücklich PowerShell 7 über pwsh.exe, erkennen den Testmodus am eigenen Dateinamen und geben bei der SendTo-Variante mit %* alle ausgewählten Ordner weiter.

            Mit `n werden lange Quell- und Zielpfade übersichtlich auf mehrere Zeilen verteilt.

            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

            • Python Grundkurs Teil 006: Ordnername als Präfix
            • PowerShell 7 Grundkurs Teil 006: Ordnername als Präfix
            • Batch Grundkurs 006: Dateien mit Ordnernamen als Präfix umbenennen
            • Python Grundkurs 005: Dateien mit einem Präfix umbenennen
            • PowerShell 7 Grundkurs 005: Dateien mit einem Präfix umbenennen

            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