Bilddateien per Powershell-Skript nach Aufnahmedatum sortiert in Ornder verschieben

xyxy_yx

Newbie
Registriert
Mai 2016
Beiträge
4
Hallo,

ich möchte alle Fotos (jpg) nach Aufnahmedatum in datumbenannte Ordner verschieben und eventuell diesen auch erstellen, wenn er nicht vorhanden ist. Die Dateien liegen im Ordner "c:\Test\sort" und die datumbenannte Ordner sollen in "c:\Test" erstellt werden.
Beispiel:
aaaaaa.jpg Erstellt am 01.04.2016 soll in den Ordner 2016.04 verschoben werden
bbbbbb.jpg Erstellt am 01.05.2016 soll in den Ordner 2016.05 verschoben werden

mein noch nicht funktionierendes Skript in Powershell:

Code:
function Get-ScriptDirectory {
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}
function Add-ExtendedFileProperties{
 <#
     .SYNOPSIS
        Fügt erweiterte Eigenschaften von Dateien an das Objekt in der Pipline hinzu
     .DESCRIPTION
        Extrahiert erweiterte Eigenschaften von Dateien wie z.B. Exif-Daten, Musik- bzw. Filmdetails
     .EXAMPLE 
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties -PropertyExtended "Bildhöhe","Bildbreite","Datenrate" | ft Name,Bildhöhe,Bildbreite,Datenrate
            Fügt alle nur die Eigenschaften "Bildhöhe","Bildbreite","Datenrate" als zusätzliche Spalten dem Objekt in der Pipline hinzu
     .EXAMPLE
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties | fl *
            Fügt alle verfügbaren erweiterten Eigenschaften dem Objekt in der Pipline hinzu
     .PARAMETER PropertyExtended
        Mit diesem Parameter geben sie eine Komma-Separierte Liste von Eigenschaften an welche sie erhalten möchten.
            -PropertyExtended "Bildhöhe","Bildbreite","Bitrate"
#>
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        $fileItem,
        [String[]] $PropertyExtended = "ALL"
    )
    begin
    {
        $shellObject = New-Object -Com Shell.Application
        $itemProperties = $null
    }
    process
    {
        if($fileItem.PsIsContainer)
        {
            $fileItem
            return
        }
        $directoryName = $fileItem.DirectoryName
        $filename = $fileItem.Name

        $folderObject = $shellObject.NameSpace($directoryName)
        $item = $folderObject.ParseName($filename)

        if(-not $itemProperties)
        {
            $itemProperties = @{}
            $counter = 0
            $columnName = ""
            if ($PropertyExtended -eq "ALL"){
                 #get all properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    if($columnName) { $itemProperties[$counter] = $columnName }
                    $counter++
                }while($columnName)
            }else{
                #get user defined properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    foreach($name in $PropertyExtended){
                        if ($columnName.toLower() -eq $name.toLower()){
                            $itemProperties[$counter] = $columnName
                        }
                    }
                    $counter++
                }while($columnName)
            }
        }

        foreach($itemProperty in $itemProperties.Keys)
        {
            $fileItem | Add-Member NoteProperty $itemProperties[$itemProperty] `
                $folderObject.GetDetailsOf($item, $itemProperty) -ErrorAction `
                SilentlyContinue
        }
        $fileItem
    }
}

$ordner = Get-ScriptDirectory
$fileordner = "$ordner\sort"

dir $fileordner -File |Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum" | group {$_.Aufnahmedatum.Substring(0,10)} | group {Get-Date $_.Aufnahmedatum -format yyyy.MM} | %{
    $ziel = "$ordner\$($_.Name)"
    if (!(test-path $ziel)){md $ziel -Force} 
    $_.Group | move-item -Destination $ziel -EA Ignore
    }

hoffe jemand kann mir weiterhelfen
schon mal danke im Voraus
 
Zuletzt bearbeitet: (Falscher Titel)
AW: Bilddateien nach Aufnahmedatum sortiert in Ornder verschieben

Und daraus willst Du nun eine Batch Datei machen?
 
AW: Bilddateien nach Aufnahmedatum sortiert in Ornder verschieben

Würd ich in python machen.. da ist das sicherlich 100x einfacher.
 
  • Gefällt mir
Reaktionen: breedmaster
AW: Bilddateien nach Aufnahmedatum sortiert in Ornder verschieben

Soll keine Batch-Datei werden. Das Skript wird in Powershell ausgeführt.
Wenn ich an dieser Stelle
Code:
... 
dir $fileordner -File |Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum" | group {$_.Aufnahmedatum.Substring(0,10)} | group {Get-Date $_.Aufnahmedatum -format yyyy.MM} | %{ ...
Code:
group {$_.Aufnahmedatum.Substring(0,10)}
weglasse gibt es folgendenFehler bei Get-Date:
Code:
group : Cannot bind parameter 'Date'. Cannot convert value "‎17.‎05.‎2015 ‏‎12:54" to type 
"System.DateTime". Error: "Die Zeichenfolge wurde nicht als gültiges DateTime erkannt."
At C:\Test\DatumSortieren.ps1:82 char:88
+ ... nahmedatum"  | group {Get-Date $_.Aufnahmedatum -format yyyy.MM} | %{
+                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (aaaaaa.JPG:PSObject) [Group-Object], ParameterBindingE 
   xception
    + FullyQualifiedErrorId : ExpressionEvaluation,Microsoft.PowerShell.Commands.GroupObjectCommand

Wie würde der Code in Phyton aussehen, da habe ich bisher noch sehr wenig Erfahrung?
 
Zuletzt bearbeitet:
AW: Bilddateien nach Aufnahmedatum sortiert in Ornder verschieben

Bitte, Titel abändern, wenn das keine BATCH Datei ist/werden soll... ist was MIAC meinte...
 
So, ich habe mal geschaut.

Das Problem ist, daß das Aufnahmedatum nicht im Format des Systemdatums vorliegt, sondern noch einige unsichtbare Zeichen enthält.

Dazu habe ich noch die Befehle etwas entzerrt. Am Ende hast Du nun jeweils das Verzeichnis und den vollen Dateinamen:
Code:
$ordner = Get-ScriptDirectory
$fileordner = "$ordner\sort"

$Dateien = dir $fileordner -File |
  Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum" 

 foreach ( $Datei in $Dateien){
  $datum=$Datei.Aufnahmedatum -replace '([^0-9.: ])',''
 
  try{
    $Verz=[DateTime]::ParseExact($datum,'dd.MM.yyyy HH:mm',         
      [System.Globalization.CultureInfo]::InvariantCulture).ToString("yyyy.MM")
      
    $Verz
    $Datei.FullName
    }
    catch{}
}
 
Zuletzt bearbeitet: ($ vergessen)
besten dank, hat wunderbar funktioniert
hier nochmal der Code, falls ihn wer benötigt:
function Get-ScriptDirectory siehe oben
function Add-ExtendedFileProperties siehe oben

Code:
$ordner = Get-ScriptDirectory
$fileordner = "$ordner\sort"
$Dateien = dir $fileordner -File | Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum" 
 foreach ( $Datei in $Dateien){
  $datum=$Datei.Aufnahmedatum -replace '([^0-9.: ])',''
 
  try{
    $Verz=[DateTime]::ParseExact($datum,'dd.MM.yyyy HH:mm', [System.Globalization.CultureInfo]::InvariantCulture).ToString("yyyy.MM")
    if (!(test-path "$ordner\$Verz")){md "$ordner\$Verz" -Force} 
    move-item $Datei.FullName -Destination "$ordner\$Verz" -EA Ignore
    }
   catch{}
}
 
Hallo,
das ist genau das was ich suche. Eine Frage dazu bitte, wie genau benutze ich das Powershell script?
Vielen Dank vorab.
Grüße
Kai
 
So habe mich jetzt extra für das Thema angemeldet... :-)

Ich habe mir jetzt das PS Skript nachgebaut.
die Funktionen hab ich davor gesetzte.
Allerdings passiert nichts. Was mach ich falsch?

Das Skript hab ich dahin gehend erweitert das der Ordner sort noch angelegt wird... das Funktioniert noch. Aber dann das Auslesen und verschieben der Dateien klappt nicht. Es kommt keine Felermeldung und auch sonst kein feedback das oder was passiert ist... Hier jetzt nun mal der Code mit dem ich arbeite:

PowerShell:
# Funktionen
function Get-ScriptDirectory {
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}

function Add-ExtendedFileProperties{
 <#
     .SYNOPSIS
        Fügt erweiterte Eigenschaften von Dateien an das Objekt in der Pipline hinzu
     .DESCRIPTION
        Extrahiert erweiterte Eigenschaften von Dateien wie z.B. Exif-Daten, Musik- bzw. Filmdetails
     .EXAMPLE
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties -PropertyExtended "Bildhöhe","Bildbreite","Datenrate" | ft Name,Bildhöhe,Bildbreite,Datenrate
            Fügt alle nur die Eigenschaften "Bildhöhe","Bildbreite","Datenrate" als zusätzliche Spalten dem Objekt in der Pipline hinzu
     .EXAMPLE
            Get-ChildItem "C:\Temp" | Add-ExtendedFileProperties | fl *
            Fügt alle verfügbaren erweiterten Eigenschaften dem Objekt in der Pipline hinzu
     .PARAMETER PropertyExtended
        Mit diesem Parameter geben sie eine Komma-Separierte Liste von Eigenschaften an welche sie erhalten möchten.
            -PropertyExtended "Bildhöhe","Bildbreite","Bitrate"
#>
    param(
        [Parameter(Mandatory=$true,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        $fileItem,
        [String[]] $PropertyExtended = "ALL"
    )
    begin
    {
        $shellObject = New-Object -Com Shell.Application
        $itemProperties = $null
    }
    process
    {
        if($fileItem.PsIsContainer)
        {
            $fileItem
            return
        }
        $directoryName = $fileItem.DirectoryName
        $filename = $fileItem.Name

        $folderObject = $shellObject.NameSpace($directoryName)
        $item = $folderObject.ParseName($filename)

        if(-not $itemProperties)
        {
            $itemProperties = @{}
            $counter = 0
            $columnName = ""
            if ($PropertyExtended -eq "ALL"){
                 #get all properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    if($columnName) { $itemProperties[$counter] = $columnName }
                    $counter++
                }while($columnName)
            }else{
                #get user defined properties
                do {
                    $columnName = $folderObject.GetDetailsOf($folderObject.Items, $counter)
                    foreach($name in $PropertyExtended){
                        if ($columnName.toLower() -eq $name.toLower()){
                            $itemProperties[$counter] = $columnName
                        }
                    }
                    $counter++
                }while($columnName)
            }
        }

        foreach($itemProperty in $itemProperties.Keys)
        {
            $fileItem | Add-Member NoteProperty $itemProperties[$itemProperty] `
                $folderObject.GetDetailsOf($item, $itemProperty) -ErrorAction `
                SilentlyContinue
        }
        $fileItem
    }
}

# Eigentliche Sortierarbeit
$ordner = Get-ScriptDirectory
$fileordner = "$ordner\sort"
if (!(test-path "$ordner\sort")){md "$ordner\sort" -Force}

$Dateien = dir $fileordner -File | Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum"

 foreach ( $Datei in $Dateien)

 {
  $datum=$Datei.Aufnahmedatum -replace '([^0-9.: ])',''
 
  try{
    $Verz=[DateTime]::ParseExact($datum,'dd.MM.yyyy HH:mm', [System.Globalization.CultureInfo]::InvariantCulture).ToString("yyyy.MM.dd")
    if (!(test-path "$ordner\$Verz")){md "$ordner\$Verz" -Force}
    move-item $Datei.FullName -Destination "$ordner\$Verz" -EA Ignore
     }
   catch{}
}

Was mich jetzt noch bisschen iritiert... ist die Variable $Datei... liegt es daran, dass diese nicht definiert wird?
Lediglich Dateien wird definiert
PowerShell:
$Dateien = dir $fileordner -File | Add-ExtendedFileProperties -PropertyExtended "Aufnahmedatum"

Ich wäre sehr dankbar wenn das bei mir auch gehen würde... es würde mir Stunden und Tage an Arbeit sparen :-)
 
Micha45 vielen Dank für den Hinweis! Das ist Richtig dort wird es definiert :-) Hab ich irgendwie übersehen :-( Aber es funktioniert bei mir nicht. Was ist den da falsch? :-(
 
Ich habe in meinem Skript oben ja gesagt, er soll den Ordner sort anlegen wenn er nicht da ist.... das macht er noch aber dann ist es leider vorbei :-(
Code:
PS C:\WINDOWS\System32> E:\TEMP\sd\Bilder_nach_Datum.ps1


    Verzeichnis: E:\TEMP\sd


Mode                LastWriteTime         Length Name                                                                                                                   
----                -------------         ------ ----                                                                                                                   
d-----       26.11.2018     06:46                sort                                                                                                                   



PS C:\WINDOWS\System32>
 
@D-keller.net

Versuche es mal so:

PowerShell:
# Eigentliche Sortierarbeit
$ordner = Get-ScriptDirectory
if (!(Test-Path "$ordner\sort")) {New-Item -ItemType Directory -Force -Path "$ordner\sort"}
$fileordner = (Get-Item "$ordner\sort").FullName
 
Vielen Dank für die Mühen!

Jetzt macht er es zwar... verschiebt die Ordner allerdings nicht in das sort Verzeichnis das er ja anlegt
Code:
d-----       26.11.2018     17:48                2015-08-27                                                                                                            
d-----       26.11.2018     17:48                2015-08-30                                                                                                            
d-----       26.11.2018     17:48                2015-09-04                                                                                                            
d-----       26.11.2018     17:48                sort

EDIT:
Hab jetzt einiges ausprobiert aber irgendwie Kopiert er mir nicht die Ordner mit Inhalt in den sort Ordner...
Dieser Schritt ist eigentlich einfach nur noch nice to have weil mir das andere schon ungemein hilft :-) Aber vielleicht kann mir ja noch jemand helfen um dazu zu lernen :-)
 
Zuletzt bearbeitet:
kann man das skript so erweitern, dass es einen fragt, ob man es nach tagen oder nach monaten sortieren will?
 
Zurück
Oben