none
Powershell Script to move files into folders based on year, month, and subfolder name RRS feed

  • Question

  • Hello,

    I am a beginner with PowerShell scripting; however, I need to organize some files based on year, month, and type of file. Each file starts with abb_numbers, abc_numbers, and aec_numbers, and where created in various years and different months. I would like for example, the 2014 files to be in a folder, with the subfolder being the month, and within the subfolder for that month and year, abb_numbers, abc_numbers, and aec_numbers, to be in separate folders within that year/month. Any help would be appreciated. I have the following which will group the files into folders, but cannot seem to get the year/month thing going.

    $root = "C:\Path\files\"

    $files = Get-ChildItem -Path $root

    ForEach ($file in $files) {

        $dir_name = $file.BaseName.Split("_")[0]
        $dir_path = Join-Path -Path $root -ChildPath $dir_name
           
        If (!(Test-Path $dir_path)) {
           
            New-Item -Path $root -Name $dir_name -ItemType Directory
       
        }
       
        Move-Item -Path $file.FullName -Destination $dir_path
     }

    Thursday, July 31, 2014 6:58 PM

Answers

  • I believe the following will do what you are looking for. This will create a Year directory for each year that a file had been created, then create a Month subfolder(again based on CreationTime), and then then a subfolder based on the first three characters of the BaseName of the file. Finally, it will move each file to the last subfolder. Additionally, there is two lines at the bottom that will move all of the files back.

    $root = "C:\Path\files"
    
    $files = Get-ChildItem -Path $root
    
    ForEach ($file in $files)
    {
        $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[0..2] -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
     }
    
    
     

    Undo line:

    ###Below will Move all the files back to the root directory.
    $undo = Get-ChildItem "C:\Path\files" -Recurse
    $undo | ? {$_.PSisContainer -eq $false} | % {Move-Item -path $_.FullName -Destination "C:\Path\files\"}
    



    • Edited by Mark Ince Friday, August 1, 2014 4:05 AM
    • Marked as answer by ITGIRL29 Friday, August 1, 2014 4:06 PM
    Thursday, July 31, 2014 11:39 PM

All replies

  • The exact filename is not specified abb_201407.??? or abb_072014.???

    If it's a one-shot deal, batch file approach

    IF "%1"=="DoYear" goto DoYear
    IF "%1"=="DoMonth" goto DoMonth
    IF "%1"=="MoveFile" goto MoveFile
    
    :Default
    set years=2010 2011 2012 2013 2014
    set months=01 02 03 04 05 06 07 08 09 10 11 12
    
    C:
    Cd \Path\Files
    
    FOR %%1 in (%Years%) do call %0 DoYear %%1
    goto end
    
    :DoYear
    FOR %%1 in (%Months%) DO call %0 DoMonth %2 %%1
    goto end
    
    :DoMonth
    FOR %%1 in (???_%2%3.???) DO call %0 MoveFile %2 %3 %%1
    goto end
    
    :MoveFile
    If not exist %2%3\. MD %2%3
    Move %4 %2%3
    goto end
    
    :end


    Thursday, July 31, 2014 7:21 PM
  • The script didn't work for me.The files will range from .lis to .xls, and .docx files. I changed the path\files to the actual directory the files are located in. I also would prefer not to hard code any numbers for the year. Thanks
    • Edited by ITGIRL29 Thursday, July 31, 2014 7:38 PM
    Thursday, July 31, 2014 7:35 PM
  • This would move file abb_201407.xls to c:\Path\Files\201407\abb

    This would move file abc_201407.xls to c:\Path\Files\201407\abc

    This would move file abe_201407.xls to c:\Path\Files\201407\abe

    $root = "C:\Path\files\"
    Set-Location -Path $Root
    $files = Get-ChildItem "." -File
    
    ForEach ($file in $files) {
    
        [string[]]$FileParts = $file.BaseName.Split(".")
        [string[]]$dir_name = $fileParts.Split("_")
    
        If (!(Test-Path -Path $Dir_Name[1])) {
            New-Item -Path $dir_name[1] -ItemType Directory
        }
        
        $SubFolder=$Dir_Name[1]+"\"+$Dir_Name[0]
    
        If (!(Test-Path -Path $SubFolder)) {
            New-Item -Path $SubFolder -ItemType Directory
        }
        
        Move-Item $file -Destination $SubFolder
     }
    

    Thursday, July 31, 2014 8:18 PM
  • Will this code group the items based on the Year and Month? I need a structure with, for example,

    Reports-is the root folder

         2014 -is sub folder

               March-is subfolder

                      abc-subfolder--on down

                      aaa

                      ade

               April

                      abc

                      aaa

                      ade

    ....and so forth...



    • Edited by ITGIRL29 Thursday, July 31, 2014 8:48 PM
    Thursday, July 31, 2014 8:42 PM
  • The exact file name(s) has still not been specified, didn't realize the months were spelled out and not numbers. The reports folder was not in the original post.

    This is only 1 level of subfolders in the root folder "C:\PATH\FILES", for example

    C:\PATH\FILES\2014

    C:\PATH\FILES\JULY

    C:\PATH\FILES\ABC

    Those three folders would be based on a filename of ABC_2014_JULY.*? OR ABC_2014JULY.* OR ?

    There will be 3 copies of it in the folder structure based on 3 bits of info in the filename?

    Thursday, July 31, 2014 9:01 PM
  • I believe the following will do what you are looking for. This will create a Year directory for each year that a file had been created, then create a Month subfolder(again based on CreationTime), and then then a subfolder based on the first three characters of the BaseName of the file. Finally, it will move each file to the last subfolder. Additionally, there is two lines at the bottom that will move all of the files back.

    $root = "C:\Path\files"
    
    $files = Get-ChildItem -Path $root
    
    ForEach ($file in $files)
    {
        $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[0..2] -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
     }
    
    
     

    Undo line:

    ###Below will Move all the files back to the root directory.
    $undo = Get-ChildItem "C:\Path\files" -Recurse
    $undo | ? {$_.PSisContainer -eq $false} | % {Move-Item -path $_.FullName -Destination "C:\Path\files\"}
    



    • Edited by Mark Ince Friday, August 1, 2014 4:05 AM
    • Marked as answer by ITGIRL29 Friday, August 1, 2014 4:06 PM
    Thursday, July 31, 2014 11:39 PM
  • This works great, after a little tweaking to my specifications. However, is there a way to place the months in the correct order? The months are somehow alphabetized..Ex. April August July June May and not April May June July..
    Friday, August 1, 2014 1:58 PM
  • Use the sorting in Windows Explorer. Right Click>Sort by Name.
    Friday, August 1, 2014 3:45 PM
  • They are sorted by name. Please disregard. Thanks for your help with everything.

    Friday, August 1, 2014 4:06 PM