Powershell Dateien nach Überprüfung in Ordnerstruktur einsortieren
Hallo,
dies ist mein erster Post hier, also seit bitte nachsichtig mir.
Ich habe eine *csv-Datei die so aussieht
und hier die Ordnerstruktur

und drei Dateien, die ich mit Hilfe von Powershell aus der CSV-Datei kopiert und umbenannt habe:
Die Spalte ID aus der CSV-Datei steht in den drei Dateien am Ende und ist jeweils der Name der einzelnen
Ordner unter TEST-Local
Ich möchte jetzt Folgendes erreichen.
1. Powershell soll die letzte Spalte der drei Dateien mit den Ordnernamen vergleichen
2. Wenn die Namen übereinstimmen soll es die entsprechende Datei in den jeweils passenden Unterordner (GROTHE) verschieben.
also so: Klaus-Schlau-SK29915M.xlsx gehört in TEST-Local\SK29915M\GROTHE
Ich weiß, dass man mit
die CSV zeilenweise auslesen kann. Und mit
kann man die Ordnerstruktur in einer Variable speichern.
Aber wie bekomme ich jetzt das Vergleichen und entsprechende Verschieben in die Unterordner hin?
Für Hilfe wäre ich sehr dankbar!
VG Thorsten
dies ist mein erster Post hier, also seit bitte nachsichtig mir.
Ich habe eine *csv-Datei die so aussieht
Vorname;Name;ID
Anton;Tunichtgut;TA29241M
Alf;Melmac;MA28943M
Klaus;Schlau;SK29915M
und hier die Ordnerstruktur

und drei Dateien, die ich mit Hilfe von Powershell aus der CSV-Datei kopiert und umbenannt habe:
Alf-Melmac-MA28943M.xlsx
Klaus-Schlau-SK29915M.xlsx
Anton-Tunichtgut-TA29241M.xlsx
Die Spalte ID aus der CSV-Datei steht in den drei Dateien am Ende und ist jeweils der Name der einzelnen
Ordner unter TEST-Local
Ich möchte jetzt Folgendes erreichen.
1. Powershell soll die letzte Spalte der drei Dateien mit den Ordnernamen vergleichen
2. Wenn die Namen übereinstimmen soll es die entsprechende Datei in den jeweils passenden Unterordner (GROTHE) verschieben.
also so: Klaus-Schlau-SK29915M.xlsx gehört in TEST-Local\SK29915M\GROTHE
Ich weiß, dass man mit
$csv = Import-CSV 'Z:\Schule\Klausuren\Klassen\TEST\00-Test-ClassData.CSV' -Delimiter ';'
$csv | %{
Write-Host $_.ID
# etc
}
die CSV zeilenweise auslesen kann. Und mit
$folders = Get-ChildItem -Path Z:\Schule\Klausuren\Klassen\TEST\TEST-Local\
kann man die Ordnerstruktur in einer Variable speichern.
Aber wie bekomme ich jetzt das Vergleichen und entsprechende Verschieben in die Unterordner hin?
Für Hilfe wäre ich sehr dankbar!
VG Thorsten
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1620263915
Url: https://administrator.de/forum/powershell-dateien-nach-ueberpruefung-in-ordnerstruktur-einsortieren-1620263915.html
Ausgedruckt am: 03.05.2025 um 10:05 Uhr
7 Kommentare
Neuester Kommentar
Moin Thorsten und herzlich willkommen im Forum.
Der Befehl prüft, ob eine Bedingung gegeben ist; und spukt am Ende nur noch die zutreffenden Objekte wieder aus.
Genauso kann man auch statt Where-Object dessen Alias ? nutzen.
Gruß Thomas
PS: Hast du schon mal einen Blick in unseren Powershell Leitfaden für Anfänger geworfen?
Zitat von @thor2511:
Aber wie bekomme ich jetzt das Vergleichen und entsprechende Verschieben in die Unterordner hin?
Für sowas nutzt man am besten den Befehl Where-Object.Aber wie bekomme ich jetzt das Vergleichen und entsprechende Verschieben in die Unterordner hin?
Der Befehl prüft, ob eine Bedingung gegeben ist; und spukt am Ende nur noch die zutreffenden Objekte wieder aus.
# Quellpfad, in dem die Ordner und Dateien liegen
$Source = 'Z:\Schule\Klausuren\Klassen\TEST\TEST-Local'
# Prüfen, ob im Quellpfad Ordner mit Name aus Spalte "ID" vorhanden sind
$CSV | Where-Object {Test-Path -Type Container "$Source\$($_.ID)\GROTHE"} | Foreach-Object {
# Dateinamen aus CSV-Zeile generieren
$Name = "$($_.Vorname)-$($_.Name)-$($_.ID).xlsx"
# Prüfen, ob XLSX-Datei im Quellpfad existiert - falls ja verschieben
if (Test-Path "$Source\$Name") { Move-Item -Path "$Source\$Name" -Destination "$Source\$($_.ID)\GROTHE" }
} # Ende der Foreach-Schleife
Hinweis:
Ich weiß, dass man mit
die CSV zeilenweise auslesen kann.
das % ist ein Alias, also eine Kurzform für den Befehl Foreach-Object.$csv | %{
Write-Host $_.ID
# etc
}
Genauso kann man auch statt Where-Object dessen Alias ? nutzen.
Gruß Thomas
PS: Hast du schon mal einen Blick in unseren Powershell Leitfaden für Anfänger geworfen?

Wenn die Dateien schon umbenannt sind reicht auch ein
$source = 'Z:\Schule\Klausuren\Klassen\TEST\TEST-Local'
Get-ChildItem $source -File | ?{Test-Path "$source\$($_.Basename.split('-')[-1])\GROTHE"} | move-item -Destination {"$source\$($_.Basename.split('-')[-1])\GROTHE"} -verbose
Zitat von @thor2511:
So sieht es jetzt aus
Dafür braucht man kein Foreach zu nutzen, die Replace-Methode lässt sich auch einfach auf Arrays anwendenSo sieht es jetzt aus
# Umlaute und Leerzeichen in CSV ersetzen
$CSVNoUmlauts = Get-Content $CSV
Foreach ($i in $CSVNoUmlauts) {
$NoUmlauts = $i.Replace('ä','ae').Replace('Ä','Ae').Replace('ö','oe').Replace('Ö','Oe').Replace('ü','ue').Replace('Ü','Ue').Replace('ß','ss').Replace(' ','')
Add-Content -Path .\NoUmlauts.csv -Value $NoUmlauts
}
# Dateiinhalt lesen, Umlaute ersetzen.
$CSVNoUmlauts = (Get-Content $CSV).Replace('ä','ae').Replace('Ä','Ae').Replace('ö','oe').Replace('Ö','Oe').Replace('ü','ue').Replace('Ü','Ue').Replace('ß','ss').Replace(' ','')
# Alte CSV mit neuer ersetzen
Move-Item .\NoUmlauts.csv -Destination $CSV -Force
# CSV nach Spalten sortieren: Vorname;Name;ID
# sonst funktioniert das Einsortieren nicht
# so ist es egal, wie die CSV vorher sortiert ist
Import-Csv $CSV -Delimiter ';' | Select Vorname, Name, ID | export-csv CSV-Sortiert.csv -Delimiter ';' -NoTypeInformation
$CsvSortiert = $CSVNoUmlauts | ConvertFrom-CSV -Delimiter ';' | Select Vorname, Name, ID
# Anführungszeichen in CSV entfernen
$CSVSortiert = Get-Content "CSV-Sortiert.csv"
$CSVSortiert = $CSVSortiert.Replace('"','') | Set-Content .\CSV-Sortiert.csv -Force
CSV-Dateiformat#Dateiaufbau
# Orginal CSV danach überschreiben
Move-Item .\CSV-Sortiert.csv -Destination $CSV -Force
Jetzt muss ich noch herausfinden, wie man das Ganze auch für mehrere Dateien auf einmal machen kann.
Foreach kennst du doch schon 😉# Arbeitsverzeichnis
$WorkingDir = "Z:\Schule\Klausuren\Klassen\TEST\TEST-Local"
# Name Unterverzeichnis
$instrName = "GROTHE"
# Alle CSV-Dateien auflisten
$CSVs = Get-ChildItem -File "$WorkingDir\*.csv"
# Zähler für bearbeitete Dateien
$i = 0
# Für jede Csv-Datei...
Foreach ($CSV in $CSVs) {
# Inhalt lesen, Umlaute ersetzen
$Content = (Get-Content $CSV).Replace('ä','ae').Replace('Ä','Ae').Replace('ö','oe').Replace('Ö','Oe').Replace('ü','ue').Replace('Ü','Ue').Replace('ß','ss').Replace(' ','')
# Text in Powershell-Objekt konvertieren
$Object = $Content | ConvertFrom-CSV -Delimiter ';'
# Für Jede Zeile des Objekts, zu der ein Ordner im Arbeitsverzeichnis existiert...
Foreach ($Line in $Object | ? {Test-Path -Type Container "$WorkingDir\$($_.ID)\$instrName"} ) {
# Dateiname aus Spalten generieren
$Name = $Line.Vorname + '-' + $Line.Nachname + '-' + $Line.Id + '.xlsx'
# Prüfen, ob XLSX-Datei im Quellpfad existiert - falls ja, verschieben und Zähler erhöhen
if (Test-Path "$WorkingDir\$Name") {
Move-Item -Path "$WorkingDir\$Name" -Destination "$WorkingDir\$($_.ID)\$instrName"
$i++
}
} # Ende Foreach Line
} # Ende Foreach CSV
write-host "$i Dateien verschoben."
Gruß Thomas