Before I take a change with live data I decide to create a small sample set for testing. In my test I create 100 .txt files in a folder. My goal with the script is to move files, 10 at a time, into a numerically sequential folders. In plain English, I want folder 1 to contain files 1.txt through 10.txt. I want folder 2 to contain files 11.txt through 20.txt. Et cetera. In designing this I know, with larger folder sets, that I really want folder names to be zero-filled. Zero-filling is when you pad the left side (in English) of a string with 0s. So, instead of folder name 1, I have can have folder 001. This way when you sort, you get a cleaner folder. Sometimes, with PowerShell, sorting on file or folder name will yield funky results, so, by equalizing all the folder names with zero-filling padded names I eliminte this issue. Yet, for giggles, I touch on a way to maximize sort with expeessions. Enough babbling. Some code.
Heres the break down of this script:$path = C:dataDocumentsPowershell est reakingsets1..100 |% {1 > "$path$_.txt"}$counter = 1;$foldercounter = 1;$foldersize = 1000;dir $path |sort @{e={$_.basename -as [Int]}} |%{# set folder name with zero filling for sorting$foldername = ("$path{0:0000}" -f $foldercounter)# if folder doesnt exist createif(!(Test-Path -Path $foldername)){$folderpath = md $foldername}# Check to see if file nameif(($counter % $foldersize) -eq 0){move $_.fullname $folderpath$foldercounter++}# if file doesntelseif(($counter % $foldersize) -ne 0){move $_.fullname $folderpath}# Increment counter$counter++}
- Line 1: specify my directory
- Line 2: enumerate an array of 100 integers (1..100)
- Lines 3-5: create 100 new files named
.txt each containing the character 1 - Line 6: set a $counter variable to 1 to keep track of file count
- Line 7: set a $foldercounter variable to 1 to help increment folder names
- Line 8: set a $foldersize variable to 10 to tell the script how many files to put in each directory
- Line 9: iterate the contents of my folder
- Line 10: sort the contents based on the file basename (that is without an extension) as if they were int objects. This gives you a different sort order than sorting on basename as strings.
- Line 13: join the $path and $foldercounter variables into one string (acting as a folder path). The neat thing here is using the format operation -f to zero-fill the folder name. So, when it runs it creates a folder named 0001 instead of 1. This helps when you get to folder 109 which is named 0109 instead.
- lines 16-19: create the folder in case it does not exist.
- line 22: test to see if the $counter variable is 0 when parsed with a modulus operator equal to the $foldersize variable. The idea here is to increment the folder name by 1 so the next time the loop iterates the script recognizes that the next folder does not exist and to create it.
- lines 24-25: move the folder to the new folder and increment the $foldercounter variable.
- lines 28-31: same thing as above except it does not increment the $foldercounter variable for the next iteration.
- line 34: increment the $counter variable one for each file that passes through the loop.
Okay, a lot to explain a simply task...I know. Nonetheless, there are a few mechanics that, if not unpacked, may not be easily spotted by folks new to this kind of task. The only thing you need to change here is the $foldersize. In fact, you could very easily create a function that looks like this (which I did for reference since this is VERY reusable code):
$basepath = C:dataDocumentsPowershell est reakingsets1..100 |% {1 > "$basepath$_.txt"}function Create-SequentialFolders{param([ValidateScript({Test-Path -Path $_})][Alias(Folder)]$path,[Int]$counter = 1,[Int]$foldercounter = 1,[Int]$foldersize = 100,[Int]$paddingcount = 3)$path$zerofill = 0 * $paddingcountGet-ChildItem -Path $path |Where-Object {!$_.PSIsContainer} |Sort-Object @{e={$_.basename -as [Int]}} |%{# set folder name with zero filling for sorting$foldername = ("$path{0:$zerofill}" -f $foldercounter)$foldername# if folder doesnt exist createif(!(Test-Path -Path $foldername)){$folderpath =