TOPTORIALS OFFICE - PowerShell 7 Grundkurs
Script: 003_Dateiliste_erstellen
Autor: Chris
YouTube: https://www.youtube.com/@TOPTORIALS-OFFICE
Webseite: https://www.toptorials.com
Letzte Aktualisierung: 2026-07-24

============================================================

1. # Was macht dieses Script?

Dieses Script erstellt automatisch eine Dateiliste mit PowerShell 7.

Es gibt zwei Varianten:

01_Einfach
02_SendTo_Dateiliste_erstellen

Die erste Variante erstellt eine Dateiliste aus dem aktuellen Ordner.
Das Script wird dazu zusammen mit der Starter-Batchdatei in den
gewünschten Ordner kopiert und dort gestartet.

Die zweite Variante ist eine SendTo-Version. Damit können Dateien oder
Ordner im Windows-Explorer markiert und über "Senden an" an das Script
übergeben werden.

Die fertige Liste kann:

* in eine Textdatei geschrieben werden
* in die Zwischenablage kopiert werden
* oder beides gleichzeitig

Dieses Script löscht keine Dateien und verändert keine vorhandenen
Dateien. Es liest Dateien und Ordner aus, erstellt eine Textdatei und
schreibt die Liste zusätzlich in die Zwischenablage.

============================================================
2. Enthaltene Ordner und Dateien
================================

01_Einfach
003_dateiliste_erstellen.ps1
003_dateiliste_erstellen_starter_batch.bat

02_SendTo_Dateiliste_erstellen
003_sendto_dateiliste_erstellen.ps1
003_sendto_dateiliste_erstellen_starter_batch.bat

============================================================
3. Variante 1: 01_Einfach
=========================

Die einfache Variante befindet sich im Ordner:

01_Einfach

Darin liegen diese Dateien:

003_dateiliste_erstellen.ps1
003_dateiliste_erstellen_starter_batch.bat

Die PowerShell-Datei enthält die eigentliche Logik.

Die Starter-Batchdatei startet PowerShell 7 mit pwsh und führt das
PowerShell-Script aus.

Empfohlener Start:

003_dateiliste_erstellen_starter_batch.bat

Diese Datei kann per Doppelklick gestartet werden.

Die Dateiliste wird aus dem Ordner erstellt, in dem die Starter-
Batchdatei liegt.

Die Ausgabe erfolgt standardmäßig in:

dateiliste.txt

Zusätzlich wird der Inhalt der Liste in die Zwischenablage kopiert.

============================================================
4. Variante 2: 02_SendTo_Dateiliste_erstellen
=============================================

Die SendTo-Variante befindet sich im Ordner:

02_SendTo_Dateiliste_erstellen

Darin liegen diese Dateien:

003_sendto_dateiliste_erstellen.ps1
003_sendto_dateiliste_erstellen_starter_batch.bat

Diese Variante ist für den praktischen Workflow im Windows-Explorer
gedacht.

Damit können Dateien oder Ordner markiert und über "Senden an" an das
Script übergeben werden.

Typischer Ablauf:

1. Im Explorer Dateien oder Ordner markieren
2. Rechtsklick auf die markierten Elemente
3. Senden an
4. SendTo-Starter-Batchdatei auswählen
5. PowerShell erstellt daraus eine Dateiliste
6. Die Liste wird als Textdatei gespeichert und in die Zwischenablage kopiert

Die Ausgabe erfolgt standardmäßig in:

dateiliste_sendto.txt

============================================================
5. SendTo-Verknüpfung einrichten
================================

Damit die SendTo-Variante über das Kontextmenü genutzt werden kann,
muss eine Verknüpfung zur Starter-Batchdatei im SendTo-Ordner von
Windows abgelegt werden.

Den SendTo-Ordner öffnen:

Windows-Taste + R

Dann eingeben:

shell:sendto

Danach Enter drücken.

In diesen Ordner kann eine Verknüpfung zu folgender Datei gelegt
werden:

003_sendto_dateiliste_erstellen_starter_batch.bat

Danach erscheint diese Verknüpfung im Windows-Explorer unter:

Rechtsklick auf Dateien oder Ordner
Senden an

============================================================
6. Warum gibt es eine Starter-Batchdatei?
=========================================

Die PowerShell-Logik steht in der .ps1-Datei.

Die Batchdatei startet nur PowerShell 7 und ruft das passende
PowerShell-Script auf.

Das hat mehrere Vorteile:

* PowerShell 7 wird gezielt mit pwsh gestartet
* die passende .ps1-Datei wird automatisch gefunden
* die Ausführungsrichtlinie kann für diesen Start umgangen werden
* der Start ist für Einsteiger einfacher
* das Fenster bleibt sichtbar
* Fehlermeldungen bleiben sichtbar
* der Aufbau bleibt über die Kursteile hinweg einheitlich
* über SendTo können Dateien und Ordner bequem übergeben werden

Wichtig:
Eine .ps1-Datei kann je nach Windows-Einstellung nicht direkt per
Doppelklick gestartet werden. Außerdem können PowerShell-Scripte durch
die Execution Policy blockiert werden.

Die Starter-Batchdatei nutzt deshalb:

pwsh -ExecutionPolicy Bypass -File "Scriptname.ps1"

Das gilt nur für diesen Start.

============================================================
7. Wichtige Begriffe der einfachen Variante
===========================================

## Get-ChildItem

Get-ChildItem listet Dateien und Ordner auf.

In diesem Script wird verwendet:

Get-ChildItem -File

Bedeutung:

Hole alle Dateien aus dem aktuellen Ordner.

Der wichtige Unterschied zu Batch:

PowerShell liefert hier Dateiobjekte, nicht nur Textzeilen.

Ein Dateiobjekt besitzt Eigenschaften wie:

Name
FullName
Extension
Length
DirectoryName
LastWriteTime
CreationTime

## -File

Der Parameter -File sorgt dafür, dass nur Dateien aufgelistet werden.

Ordner werden dabei nicht ausgegeben.

## -Recurse

Der Parameter -Recurse bezieht Unterordner mit ein.

Nicht rekursiv:

$dateien = Get-ChildItem -File

Rekursiv:

$dateien = Get-ChildItem -File -Recurse

Wichtig:
Es sollte immer nur eine dieser beiden Varianten aktiv sein.

## $dateien

$dateien ist eine Variable.

In dieser Variable werden die gefundenen Dateiobjekte gespeichert.

Beispiel:

$dateien = Get-ChildItem -File

Danach enthält $dateien nicht nur Dateinamen als Text, sondern echte
Dateiobjekte.

## ForEach-Object

ForEach-Object verarbeitet jedes Objekt aus der Pipeline einzeln.

Beispiel:

$liste = $dateien | ForEach-Object {
$_.Name
}

Bedeutung:

Nimm alle Dateiobjekte aus $dateien.
Gehe jedes Objekt einzeln durch.
Nimm von jedem Objekt nur den Namen.
Speichere alle Namen in $liste.

## $_

$_ steht in ForEach-Object für das aktuelle Objekt in der Pipeline.

Beispiel:

1. Durchlauf:
   $_ = erste Datei

2. Durchlauf:
   $_ = zweite Datei

3. Durchlauf:
   $_ = dritte Datei

## $_.Name

.Name ist eine Eigenschaft eines Dateiobjekts.

$_.Name bedeutet:

Gib vom aktuellen Dateiobjekt den Namen aus.

Beispiel:

bild_start.jpg

## $_.FullName

.FullName ist ebenfalls eine Eigenschaft eines Dateiobjekts.

$_.FullName bedeutet:

Gib vom aktuellen Dateiobjekt den vollständigen Pfad aus.

Beispiel:

C:\TOPTORIALS_CODE...\bild_start.jpg

## Resolve-Path

Resolve-Path löst einen Pfad auf.

In diesem Script wird es für relative Pfade verwendet:

Resolve-Path -Path $_.FullName -Relative

Bedeutung:

Nimm den vollständigen Pfad der aktuellen Datei und gib ihn relativ zum
aktuellen Ordner aus.

Beispiel:

Vollständiger Pfad:

C:\TOPTORIALS_CODE\010_PowerShell_7_Grundkurs\003_Dateiliste_erstellen\01_Einfach\Bilder\bild01.png

Relativer Pfad:

.\Bilder\bild01.png

Der Punkt steht für den aktuellen Ordner.

Merksatz:

FullName ist bereits vorhanden.
Relative Pfade müssen berechnet werden.

============================================================
8. Listenvarianten in der einfachen Version
===========================================

In der einfachen Variante gibt es mehrere Möglichkeiten.

Wichtig:
Immer nur eine Listenvariante aktiv lassen.

## Variante 1: Nur Dateinamen

$liste = $dateien | ForEach-Object {
$_.Name
}

Beispielausgabe:

archiv_test.zip
bild_start.jpg
notiz.txt
protokoll.log
rechnung_maerz.pdf

## Variante 2: Relative Pfade

$liste = $dateien | ForEach-Object {
Resolve-Path -Path $_.FullName -Relative
}

Beispielausgabe:

.\Bilder\bild01.png

## Variante 3: Absolute Pfade

$liste = $dateien | ForEach-Object {
$_.FullName
}

Beispielausgabe:

C:\TOPTORIALS_CODE...\bild_start.jpg

============================================================
9. Ausgabe in Datei und Zwischenablage
======================================

## Set-Content

Set-Content schreibt Inhalt in eine Datei.

In diesem Script:

$liste | Set-Content -Path $ausgabeDatei -Encoding UTF8

Bedeutung:

Nimm $liste und schreibe den Inhalt in die Datei $ausgabeDatei.

Die Bestandteile:

$liste
= fertige Textliste

|
= Pipeline

Set-Content
= Inhalt in eine Datei schreiben

-Path $ausgabeDatei
= Ziel-Datei

-Encoding UTF8
= Datei als UTF-8 speichern

Wichtig:
Set-Content ersetzt vorhandenen Inhalt.

Wenn die Datei bereits existiert, wird sie neu geschrieben.

## Add-Content

Add-Content würde Inhalt an eine bestehende Datei anhängen.

Unterschied:

Set-Content
= Datei neu schreiben oder vorhandenen Inhalt ersetzen

Add-Content
= Inhalt an eine bestehende Datei anhängen

Für dieses Script ist Set-Content richtig, weil bei jedem Start eine
neue aktuelle Dateiliste erstellt werden soll.

## Set-Clipboard

Set-Clipboard kopiert Inhalt in die Zwischenablage.

In diesem Script:

$liste | Set-Clipboard

Bedeutung:

Nimm $liste und kopiere den Inhalt in die Zwischenablage.

Danach kann die Liste mit STRG + V in ein anderes Programm eingefügt
werden.

Beispiele:

Editor
WordPress
Excel
LibreOffice Calc
E-Mail
Dokumentation

## Get-Clipboard

Get-Clipboard wäre das Gegenstück zu Set-Clipboard.

Damit kann der aktuelle Inhalt der Zwischenablage gelesen werden.

Beispiel:

$inhalt = Get-Clipboard

Für dieses Script brauchen wir Get-Clipboard nicht, weil wir nur in die
Zwischenablage schreiben.

============================================================
10. Wichtige Begriffe der SendTo-Variante
=========================================

## param

Der param-Block legt fest, welche Werte ein PowerShell-Script beim
Start entgegennehmen kann.

In diesem Script:

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

## $Elemente

$Elemente enthält die Dateien oder Ordner, die über SendTo an das
Script übergeben wurden.

Zu Beginn sind das Textwerte, also Pfade als Text.

## [string[]]

[string[]] bedeutet:

Liste aus Textwerten.

[string] wäre ein einzelner Textwert.

[string[]] kann mehrere Textwerte enthalten.

## ValueFromRemainingArguments

ValueFromRemainingArguments sorgt dafür, dass alle restlichen
übergebenen Argumente in diesem Parameter gesammelt werden.

Das ist wichtig, wenn mehrere Dateien oder Ordner über "Senden an"
übergeben werden.

Merksatz:

[string[]]
= kann mehrere Textwerte speichern

ValueFromRemainingArguments
= sammelt alle restlichen übergebenen Werte ein

## if (-not $Elemente -or $Elemente.Count -eq 0)

Diese Bedingung prüft, ob überhaupt Dateien oder Ordner übergeben
wurden.

Bedeutung:

-not $Elemente
= es gibt keinen brauchbaren Wert in $Elemente

-or
= oder

$Elemente.Count -eq 0
= die Anzahl der Elemente ist 0

Die Bedingung bedeutet:

Wenn keine Elemente übergeben wurden oder die Anzahl der Elemente 0 ist,
dann zeige eine Meldung an und beende das Script.

Noch deutlicher mit Klammern:

if ((-not $Elemente) -or ($Elemente.Count -eq 0)) {

## Test-Path

Test-Path prüft, ob ein Pfad existiert.

Beispiel:

Test-Path -Path $element

Bedeutung:

Prüfe, ob der Pfad in $element wirklich existiert.

## Get-Item

Get-Item holt zu einem Pfad das passende Datei- oder Ordnerobjekt.

Beispiel:

Get-Item -Path $element

Vorher:

$element
= Textpfad

Nach Get-Item:

Datei- oder Ordnerobjekt mit Eigenschaften wie:

Name
FullName
Extension
Length
LastWriteTime
PSIsContainer

## $uebergebeneElemente

$uebergebeneElemente enthält die gültigen Datei- und Ordnerobjekte, die
aus den übergebenen Textpfaden erzeugt wurden.

Im Script:

$uebergebeneElemente = foreach ($element in $Elemente) {
if (Test-Path -Path $element) {
Get-Item -Path $element
}
}

PowerShell führt die foreach-Schleife aus.

Alles, was die Schleife ausgibt, wird gesammelt und in
$uebergebeneElemente gespeichert.

Gedanklich:

Für jeden übergebenen Pfad:
Wenn der Pfad existiert:
hole das Datei- oder Ordnerobjekt
sammle dieses Objekt in $uebergebeneElemente

Eine ausführlichere Schreibweise wäre:

$uebergebeneElemente = @()

foreach ($element in $Elemente) {
if (Test-Path -Path $element) {
$uebergebeneElemente += Get-Item -Path $element
}
}

## PSIsContainer

PSIsContainer ist eine Eigenschaft eines Datei- oder Ordnerobjekts.

Bei normalen Windows-Pfaden gilt praktisch:

Ordner = True
Datei  = False

Damit kann das Script unterscheiden, ob ein übergebenes Element ein
Ordner oder eine Datei ist.

Beispiel:

if ($element.PSIsContainer) {
# Ordner
} else {
# Datei
}

============================================================
11. Listenvarianten in der SendTo-Version
=========================================

Auch in der SendTo-Version gibt es mehrere Möglichkeiten.

Wichtig:
Immer nur eine Listenvariante aktiv lassen.

## Variante 1: Nur Namen der markierten Dateien und Ordner

$liste = $uebergebeneElemente | ForEach-Object {
$_.Name
}

Diese Variante gibt nur die Namen der markierten Dateien und Ordner aus.

Wenn ein Ordner markiert wurde, wird nur der Name dieses Ordners
ausgegeben. Es wird in dieser Variante nicht automatisch in den Ordner
hineingeschaut.

## Variante 2: Vollständige Pfade der markierten Dateien und Ordner

$liste = $uebergebeneElemente | ForEach-Object {
$_.FullName
}

Diese Variante gibt die vollständigen Pfade der markierten Elemente aus.

## Variante 3: Rekursiv - absolute Pfade aller Dateien

$liste = foreach ($element in $uebergebeneElemente) {
if ($element.PSIsContainer) {
Get-ChildItem -Path $element.FullName -File -Recurse | ForEach-Object {
$_.FullName
}
} else {
$element.FullName
}
}

Diese Variante prüft jedes übergebene Element.

Wenn es ein Ordner ist, wird dieser Ordner rekursiv durchsucht.
Alle gefundenen Dateien werden mit vollständigem Pfad ausgegeben.

Wenn es eine einzelne Datei ist, wird ihr vollständiger Pfad direkt
übernommen.

## Variante 4: Rekursiv - relative Pfade aller Dateien

$liste = foreach ($element in $uebergebeneElemente) {
if ($element.PSIsContainer) {
Get-ChildItem -Path $element.FullName -File -Recurse | ForEach-Object {
Resolve-Path -Path $_.FullName -Relative
}
} else {
Resolve-Path -Path $element.FullName -Relative
}
}

Diese Variante funktioniert ähnlich wie Variante 3, gibt aber relative
Pfade aus.

Beispiel:

.\Bilder\bild01.png

Der Punkt steht für den aktuellen Ordner.

============================================================
12. Wichtige Batch-Begriffe der Starter-Dateien
===============================================

## chcp 65001 >nul

Diese Zeile setzt die Codepage der Eingabeaufforderung auf UTF-8.

65001 steht für UTF-8.

> nul sorgt dafür, dass die Rückmeldung von chcp nicht angezeigt wird.

## cd /d "%~dp0"

Diese Zeile wechselt in den Ordner der Starter-Batchdatei.

%~dp0 steht in einer Batchdatei für den Ordner, in dem die Batchdatei
selbst liegt.

Wichtig:
%~dp0 enthält bereits den abschließenden Backslash.

Deshalb wird zuerst mit

cd /d "%~dp0"

in den Ordner gewechselt. Danach wird die PowerShell-Datei nur noch
über ihren Dateinamen gestartet.

Das ist übersichtlich und vermeidet doppelte Backslashes im Pfad.

/d sorgt dafür, dass der Ordnerwechsel auch funktioniert, wenn dabei
das Laufwerk gewechselt werden muss.

## pwsh

pwsh startet PowerShell 7.

Beispiel:

pwsh -ExecutionPolicy Bypass -File "003_dateiliste_erstellen.ps1"

## -ExecutionPolicy Bypass

Dieser Parameter umgeht für diesen Start die PowerShell-
Ausführungsrichtlinie.

Das gilt nur für diesen Aufruf.

## -File

Nach -File folgt die PowerShell-Datei, die gestartet werden soll.

## %*

%* steht in Batch für alle übergebenen Parameter.

In der SendTo-Starter-Batchdatei wird damit die komplette Übergabe an
PowerShell weitergereicht.

Beispiel:

pwsh -ExecutionPolicy Bypass -File "003_sendto_dateiliste_erstellen.ps1" %*

Wichtig:

%*
= alle Parameter weitergeben

"%*"
= alles zu einem einzigen Parameter zusammenfassen

Deshalb wird %* hier nicht zusätzlich komplett in Anführungszeichen
gesetzt.

## "%~1"

"%~1" wäre für einen einzelnen Parameter sinnvoll.

%1 steht für den ersten übergebenen Parameter.
%~1 entfernt äußere Anführungszeichen.
"%~1" setzt selbst wieder saubere Anführungszeichen darum.

Für mehrere übergebene Dateien oder Ordner ist hier aber %* richtig.

============================================================
13. UTF-8 und Umlaute
=====================

Für diese Kursreihe sollten die Scriptdateien als UTF-8 gespeichert
werden.

Die Starter-Batchdateien setzen zusätzlich die Codepage auf UTF-8:

chcp 65001 >nul

Die PowerShell-Dateien schreiben Textdateien mit:

-Encoding UTF8

Das hilft bei Umlauten und Sonderzeichen.

In Visual Studio Code sieht man die Kodierung normalerweise unten
rechts in der Statusleiste. Dort sollte UTF-8 stehen.

============================================================
14. Testmodus und Sicherheit
============================

Dieses Script liest Dateien und Ordner aus.

Es löscht keine Dateien.
Es verschiebt keine Dateien.
Es benennt keine Dateien um.
Es verändert keine vorhandenen Dateien.

Es erstellt aber eine neue Textdatei:

dateiliste.txt

oder bei der SendTo-Variante:

dateiliste_sendto.txt

Wenn diese Datei bereits existiert, wird der Inhalt durch Set-Content
ersetzt.

Außerdem wird der Inhalt der Liste in die Zwischenablage kopiert.

Empfehlung:

Nicht direkt mit wichtigen Originaldateien testen.
Zuerst in einem separaten Testordner ausprobieren.
Danach kontrollieren, ob die erzeugte Dateiliste wie erwartet aussieht.

Die Nutzung erfolgt auf eigene Verantwortung.

============================================================
15. Typische Fehler
===================

## PowerShell 7 wurde nicht gefunden

Wenn pwsh nicht gefunden wird, ist PowerShell 7 wahrscheinlich nicht
installiert oder nicht im Systempfad verfügbar.

Prüfen mit:

pwsh --version

## .ps1-Datei kann nicht gestartet werden

Wenn PowerShell-Scripte blockiert werden, kann das an der Execution
Policy liegen.

Die Starter-Batchdatei verwendet:

-ExecutionPolicy Bypass

Das gilt nur für diesen Start.

## Keine Elemente bei SendTo übergeben

Wenn die SendTo-Starter-Batchdatei direkt per Doppelklick gestartet
wird, wurden keine Dateien oder Ordner übergeben.

Dann erscheint eine Meldung wie:

Bitte markiere Dateien oder Ordner und sende sie an dieses Skript.

Die SendTo-Variante ist dafür gedacht, dass Dateien oder Ordner über
"Senden an" übergeben werden.

## Nur ein Eintrag in der SendTo-Liste

Wenn nur ein Ordner markiert wurde und Variante 1 aktiv ist, ist das
korrekt. Variante 1 gibt nur den Namen des markierten Elements aus.

Wenn mehrere Dateien markiert wurden, sollte in der Batchdatei %*
verwendet werden und im PowerShell-Script:

[Parameter(ValueFromRemainingArguments = $true)]
[string[]]$Elemente

Dadurch werden mehrere übergebene Dateien zuverlässig gesammelt.

## Mehrere Listenvarianten gleichzeitig aktiv

Wenn mehrere Listenvarianten gleichzeitig aktiv sind, wird $liste
mehrfach gesetzt.

Dann gilt am Ende die letzte aktive Variante.

Deshalb:

Immer nur eine Listenvariante aktiv lassen.

## Relative Pfade beginnen mit .\

Relative Pfade können so aussehen:

.\Bilder\bild01.png

Das ist korrekt.

Der Punkt steht für den aktuellen Ordner.

## Umlaute werden falsch angezeigt

Wenn Umlaute falsch angezeigt werden, prüfen:

* Datei als UTF-8 gespeichert?
* VS Code unten rechts auf UTF-8?
* Starter-Batchdatei nutzt chcp 65001?
* Set-Content nutzt -Encoding UTF8?

============================================================
16. Wichtige Lernpunkte
=======================

In diesem Teil sieht man unter anderem:

* wie Dateien mit Get-ChildItem aufgelistet werden
* warum Get-ChildItem Dateiobjekte liefert
* wie man mit .Name nur den Dateinamen ausliest
* wie man mit .FullName den vollständigen Pfad ausliest
* wie -File nur Dateien auswählt
* wie -Recurse Unterordner mit einbezieht
* wie ForEach-Object Objekte aus der Pipeline verarbeitet
* wofür $_ steht
* wie Resolve-Path -Relative relative Pfade berechnet
* wie Set-Content eine Textdatei schreibt
* wie Set-Clipboard die Zwischenablage befüllt
* wie param Startparameter entgegennimmt
* wie [string[]] mehrere Textwerte speichern kann
* warum ValueFromRemainingArguments bei SendTo wichtig ist
* wie Test-Path prüft, ob ein Pfad existiert
* wie Get-Item aus einem Textpfad ein Datei- oder Ordnerobjekt macht
* wie PSIsContainer Ordner und Dateien unterscheidet
* warum %* in Batch alle Parameter weitergibt
* warum "%*" mehrere Parameter zu einem einzigen Parameter machen würde
* warum immer nur eine Listenvariante aktiv sein sollte

============================================================
17. Kurz zusammengefasst
========================

## 01_Einfach

Diese Variante erstellt eine Dateiliste aus dem aktuellen Ordner.

Gut zum Verstehen der Grundlogik.

## 02_SendTo_Dateiliste_erstellen

Diese Variante erstellt eine Dateiliste aus übergebenen Dateien oder
Ordnern.

Gut für den praktischen Workflow im Windows-Explorer.

Die einfache Variante ist gut zum Lernen.
Die SendTo-Variante ist besser für den Alltag.

Die Nutzung erfolgt auf eigene Verantwortung.
