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
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 -Directoryermittelt die direkten Unterordner.Get-ChildItem -Fileermittelt nur die direkt enthaltenen Dateien.$ordner.Nameliefert den Namen, der als Präfix verwendet wird.Join-Pathsetzt Ordnerpfad und neuen Dateinamen sicher zusammen.StartsWitherkennt ein bereits vorhandenes Präfix ohne Beachtung der Groß- und Kleinschreibung.Test-Pathschützt bereits vorhandene Zieldateien.[PSCustomObject]speichert die geplanten Umbenennungen mit Quelle und Ziel.Rename-Itemführt die eigentliche Umbenennung erst nach der Prüfung aus.tryundcatchfangen 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
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
_testwird PowerShell 7 mit dem Schalter-Testaufgerufen. - Ohne
_teststartet 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
- Mit Windows + R den Dialog Ausführen öffnen.
shell:sendtoeingeben und mit Enter bestätigen.- Eine Verknüpfung zur Starter-Batchdatei in diesem Ordner anlegen.
- 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
-Directorywerden nur Ordner und mit-Filenur 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.
tryundcatch- 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
_testenthä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

