none
archive files based on creation date.. RRS feed

  • Question

  • Hello, I am attempting to create a powershell script that will move files to various folders based on their creation date. After 7 days, the files are moved into the appropriate folder. Please take a look at the code below, to help me figure out what I am doing wrong. Coded in Powershell.

    $root = "C:\Path"

    $files = Get-ChildItem -Path $root


    $ArchiveDate = (Get-Date).AddDays(-7)

    {


    ForEach ($file in $files)

    Where-Object {$_.LastWriteTime -lt $ArchiveDate

    {

        $year = $file.CreationTime.Year

        $month = $file.CreationTime.ToString("MMMM")

        $dir_path = Join-Path -Path $root -ChildPath $year

        $dir_path_month = Join-Path $dir_path -ChildPath $month

        $letters = $file.BaseName.Split[_] -join ""

        $dir_sub_full = Join-Path -Path $dir_path_month -ChildPath $letters

        If (!(Test-Path $dir_path)) {

           

            New-Item -Path $root -Name $year -ItemType Directory

       

        }

        If (!(Test-Path $dir_path_month))

        {

            New-Item -Path $root\$year\ -Name $month -ItemType Directory

        }

        If (!(Test-Path $dir_sub_full))

        {

            New-Item -Path $root\$year\$month -Name $letters -ItemType Directory

        }

        Move-Item -Path $file.FullName -Destination $dir_sub_full

    }

    }

    Friday, August 1, 2014 7:17 PM

Answers

  • You're processing the files for their LastWriteTime, which is different from CreationTime.

    You are using the Where-Object at the wrong location in the code.

    Also, please use the code button when posting blocks of code, it provides color highlighting and is far easier to read. Its right next to HTML on the top bar when writing a post.  

    You can do the following:

    $root = "C:\Path"
    $archivefiles = Get-ChildItem -Path $Root | 
    Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)}
    
    ForEach($file in $archivefiles)
    {
        $year = $file.CreationTime.Year
        $month = $file.CreationTime.ToString("MMMM")
        $dir_path = Join-Path -Path $root -ChildPath $year
        $dir_path_month = Join-Path $dir_path -ChildPath $month
        $letters = $file.BaseName.Split("_") -join ""
        $dir_sub_full = Join-Path -Path $dir_path_month -ChildPath $letters
        If (!(Test-Path $dir_path)) 
        {
            New-Item -Path $root -Name $year -ItemType Directory
        }
        If (!(Test-Path $dir_path_month))
        {
            New-Item -Path $root\$year\ -Name $month -ItemType Directory
        }
        If (!(Test-Path $dir_sub_full))
        {
            New-Item -Path $root\$year\$month -Name $letters -ItemType Directory
        }
        Move-Item -Path $file.FullName -Destination $dir_sub_full
    }




    • Edited by Mark Ince Friday, August 1, 2014 10:04 PM Mixed up my left from my right
    • Marked as answer by ITGIRL29 Tuesday, August 5, 2014 7:08 PM
    Friday, August 1, 2014 9:58 PM
  • $letters = $file.BaseName.Split("_")[0] is correct.

    Alright, to finish this off, I am working on taking a backup of the root folder and all of its contents. Then copy it to another server, prior to the folder changes, and keep the last two backups. So I may be posting again :) Thanks for your help.

    • Marked as answer by ITGIRL29 Tuesday, August 5, 2014 7:08 PM
    Monday, August 4, 2014 8:23 PM

All replies

  • You're processing the files for their LastWriteTime, which is different from CreationTime.

    You are using the Where-Object at the wrong location in the code.

    Also, please use the code button when posting blocks of code, it provides color highlighting and is far easier to read. Its right next to HTML on the top bar when writing a post.  

    You can do the following:

    $root = "C:\Path"
    $archivefiles = Get-ChildItem -Path $Root | 
    Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)}
    
    ForEach($file in $archivefiles)
    {
        $year = $file.CreationTime.Year
        $month = $file.CreationTime.ToString("MMMM")
        $dir_path = Join-Path -Path $root -ChildPath $year
        $dir_path_month = Join-Path $dir_path -ChildPath $month
        $letters = $file.BaseName.Split("_") -join ""
        $dir_sub_full = Join-Path -Path $dir_path_month -ChildPath $letters
        If (!(Test-Path $dir_path)) 
        {
            New-Item -Path $root -Name $year -ItemType Directory
        }
        If (!(Test-Path $dir_path_month))
        {
            New-Item -Path $root\$year\ -Name $month -ItemType Directory
        }
        If (!(Test-Path $dir_sub_full))
        {
            New-Item -Path $root\$year\$month -Name $letters -ItemType Directory
        }
        Move-Item -Path $file.FullName -Destination $dir_sub_full
    }




    • Edited by Mark Ince Friday, August 1, 2014 10:04 PM Mixed up my left from my right
    • Marked as answer by ITGIRL29 Tuesday, August 5, 2014 7:08 PM
    Friday, August 1, 2014 9:58 PM
  • This code would work great if it didn't put all of the individual files into folders. the files are labeled, for example, abc_123, abc_456, efg_890. All files starting with abc should be in an abc folder and all files starting with efg should be in an efg folder.

    Monday, August 4, 2014 4:02 PM
  • Your change to my previous response in the other thread is what caused all of the files to be moved into their own folders. I figured that's what you wanted then. Change $letters back to how I had it, if each of your files are prefaced with 3 letters as a label.

    $letters = $file.BaseName[0..2] -join ""
    #Above grabs the first three letters of the BaseName of the file.
    
    #To the below, which removes underscores.
    
    $letters = $file.BaseName.Split("_") -join ""

    Monday, August 4, 2014 4:35 PM
  • I changed my mind and wanted it delimiter to be the _. it was working before the archive piece was added..

    Monday, August 4, 2014 5:39 PM
  • Then don't join it afterwards.  The below line will grab all of the characters before the first underscore in the filename.

    $letters = ($file.BaseName.Split("_"))[0]

    Monday, August 4, 2014 5:55 PM
  • $letters = $file.BaseName.Split("_")[0] is correct.

    Alright, to finish this off, I am working on taking a backup of the root folder and all of its contents. Then copy it to another server, prior to the folder changes, and keep the last two backups. So I may be posting again :) Thanks for your help.

    • Marked as answer by ITGIRL29 Tuesday, August 5, 2014 7:08 PM
    Monday, August 4, 2014 8:23 PM