Move Groups of Files from List (Array)

Hello,

I just created a script that will loop through a CSV file that will:

  1. Create a folder
  2. Get the first ‘n’ number of files to move
  3. Move those identified files by name in a 2nd level loop (foreach)
# Root Path
$RootPath = 'D:\_TEMP\Move_Files'

# Source File
$csv_file = "$RootPath\Move_Files.csv"

# Import CSV > Process each row of data
$data = Import-CSV $csv_file | ForEach-Object{
    # Create Folder
    New-Item -ItemType Directory -Name $_.folder #-WhatIf
    # Get n files to be moved
    $files = (Get-ChildItem -Path $RootPath -Filter "*.png" | Select-Object -First $_.Files).name
    
    # Pause execution for .25 seconds
    Start-Sleep -Seconds .25
    # Move Files
    foreach ($file in $files){
        Move-Item $file -Destination $_.folder #-WhatIf
    }
}

I ran into an issue where some files didn’t wind up in the correct folder. For example, IMG_3687.PNG was skipped, while IMG_3688.PNG ended up in the folder by mistake. Appears to be a filesystem refresh issue as my first test had issues with the folder not existing, so I added a 1/4 second delay and no issues. However, on a larger batch of files, I ran into this 2nd issue regarding those PNG files.

I’m thinking the best approach would be to just create a list of all the PNG files in the directory instead of doing that within the loop for each group/batch of files.

However, I’m not entirely sure how to use the 2nd array and continue down that list, while at the same time looping through my source file that contains the number of files that need to be moved.

My CSV file contains 3 columns:
Folder,Files,Order

The Folder name to be created, the number of Files that will be moved to that Folder, and the Order of processing the files/folders. The CSV files is sorted by the Order column as they line up with the order of the PNG files in the source folder.

Thank you; any help would be greatly appreciated…

Hmmm … you’re overcomplicating this a little I think … This should work:

Import-CSV $csv_file | 
ForEach-Object{
    New-Item -ItemType Directory -Name $_.folder #-WhatIf
    
    Get-ChildItem -Path $RootPath -Filter '*.png' | 
        Select-Object -First $_.Files |
            Move-Item -Destination $_.folder
    }

Edit:

BTW:

If you set the “$RootPath” outside of the loop you’re copying the same files again and again just to different target folders contained in your CSV file. Is that by purpose?

1 Like

Hi Olaf,

Good to hear from you… it’s been awhile since I’ve come here for help. Kinda took a step back from POSH… and I absolutely regret it. I feel completely lost again.

I can’t argue with that. :slight_smile:

I’m moving the files which is why I’m experience that system refresh issue.

Ironically, when I first ran your code, I thought it was copying the files. I noticed after the test was done, the files I expected to MOVE were still there. It turns out that POSH handles Selections differently based on the filesystem. I never knew that, and it makes sense considering it was moving files based on when they were created and not by the filename.

So, after some more online research, it turns out I needed to Sort the data before piping it into Select-Object. That worked and I just ran another test against 140 files and all were moved to the correct place.

A side note: I used that same method to Sort my CSV import so I didn’t have to do it manually before importing the data. :+1:t3:

Final results with your code and my inserted Sort-Objects:

# Root Path
$RootPath = '\\nas\photo\Questions'

# Source File
$csv_file = "$RootPath\Move_Files.csv"

Import-CSV $csv_file | Sort-Object { [double]$_.order } |
ForEach-Object{
    New-Item -ItemType Directory -Name $_.folder #-WhatIf
    
    Get-ChildItem -Path $RootPath -Filter '*.png' | Sort-Object Name |
        Select-Object -First $_.Files |
            Move-Item -Destination $_.folder #-Force #-WhatIf
}

Thank you again, Olaf. This was very helpful…

You’re right. :ok_hand:t3: I think my mind stuck with a copy job - not a move job. :man_shrugging:t3: