Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell: Move files to folder based on Date Created

Tags:

powershell

I'm not a coder but I've still attempted tweaking PS scripts found here and still can't get the behavior I desire. The tough part for me has been the 2 digit Day requirement (dd). After several noob attempts I would like some help.

I have a folder that contains hundreds of JPG's. I manually sort these JPG's into folders based on the date taken. Folder name examples are 2015.02.04, 2016.10.31, 2016.12.01.

1) I would like a script to scan my JPG folder. 2) For each file, scan the date 3) If the file was created June 1st, 2016 then it will be moved to .\2016.06.01

Help a brother out?

$Filepath = ""
$file = ""
$date  = ""
$month   = ""
$year    = ""
$MonthPath   = ""

$FilePath = Read-Host "Place the directory which contains the files."

Write-Warning "Note: This action can take several minutes, depending on the amount of files in $FilePath."

get-childitem $FilePath | % {

  $file = $_.FullName 
    $date = Get-Date ($_.LastWriteTime)

  $month = $date.month
  $year = $date.year
  $day = $date.day
    $MonthPath = "$FilePath\$year.$month.$day"
    Write-Verbose "month = $month"
    Write-Verbose "Date = $date"
    Write-Verbose "year = $year"
    Write-Verbose "FilePath = $FilePath" 
    Write-Verbose "Filename = $file"
    Write-Verbose "MonthPath = $MonthPath"

    if(!(Test-Path -Path "$MonthPath" )){
        Write-Verbose "Creating log location $MonthPath."
        #Write-Host -backgroundcolor green -ForegroundColor black "Creating log location $MonthPath."
        Write-Verbose "MonthPath inside path test = $MonthPath"
        New-Item -ItemType directory -Path $MonthPath | Out-null
    }
    ELSE {
        #Write-Host -backgroundcolor green -ForegroundColor black "Log location exists already exist $MonthPath"
        Write-Verbose "Log location exists already exist $MonthPath" 
        }
    move-item "$file" "$MonthPath" | Out-null
}

Write-Warning "All files are sorted now based upon year and month."
like image 529
Sab Avatar asked Feb 06 '23 23:02

Sab


2 Answers

[DateTime]$start_time="2016-6-1 00:00:00"
[DateTime]$end_time="2016-6-1 23:59:59"
$des_folder = "C:\test\2016.06.1"

Get-ChildItem c:\test\*.jpg -Recurse | foreach {if($_.lastwritetime -ge $start_time -and $_.lastwritetime -le $end_time) { move-item $_.fullname $des_folder }}

Please ensure there is no name conflict . You may change"c:\test" in "c:\test*.jpg" to the path you want to scan . Also the value of variable "$des_folder" to the destination folder you want to store the matched pictures .

EDIT:

Get-ChildItem c:\test\test2\*.jpg -Recurse | foreach { 
$x = $_.LastWriteTime.ToShortDateString()
$new_folder_name = Get-Date $x -Format yyyy.MM.dd
$des_path = "c:\test\test2\$new_folder_name"

if (test-path $des_path){ 
    move-item $_.fullname $des_path 
    } else {
    new-item -ItemType directory -Path $des_path
    move-item $_.fullname $des_path 
    }
}
like image 68
Elton Ji - MSFT Avatar answered Feb 15 '23 11:02

Elton Ji - MSFT


I ended up creating a script that does exactly what you're asking for here. You can find it in GitHub here, which will have the latest version of the code.

Here is the current implementation, edited for conciseness, removed unnecessary features, and tailored to the question's needs:

[string] $SourceDirectoryPath = 'C:\FilesToMove'
[string] $TargetDirectoryPath = 'C:\SortedFiles'

[System.Collections.ArrayList] $filesToMove = Get-ChildItem -Path $SourceDirectoryPath -File -Force -Recurse

$filesToMove | ForEach-Object {
    [System.IO.FileInfo] $file = $_

    [DateTime] $fileDate = $file.LastWriteTime
    [string] $dateDirectoryName = $fileDate.ToString('yyyy.MM.dd')
    [string] $dateDirectoryPath = Join-Path -Path $TargetDirectoryPath -ChildPath $dateDirectoryName

    if (!(Test-Path -Path $dateDirectoryPath -PathType Container))
    {
        Write-Verbose "Creating directory '$dateDirectoryPath'."
        New-Item -Path $dateDirectoryPath-ItemType Directory -Force > $null
    }

    [string] $filePath = $file.FullName
    Write-Information "Moving file '$filePath' into directory '$dateDirectoryPath'."
    Move-Item -Path $filePath -Destination $dateDirectoryPath
}

Note that it copies the file paths into an array before iterating over them. This is important for the cases where you are copying files to subdirectories of their current directory, otherwise Get-ChildItem could scan files twice, iterating over files that it just moved.

like image 34
deadlydog Avatar answered Feb 15 '23 10:02

deadlydog