Search code examples
windowspowershellmkdirget-childitem

Powershell: Place all files in a specified directory into separate, uniquely named subdirectories


I have an existing directory, let's say "C:\Users\Test" that contains files (with various extensions) and subdirectories. I'm trying to write a Powershell script to that will put each file in "C:\Users\Test" into a uniquely named subdirectory, such as "\001", "\002", etc., while ignoring any existing subdirectories and files therein. Example:

Before running script:

C:\Users\Test\ABC.xlsx
C:\Users\Test\QRS.pdf
C:\Users\Test\XYZ.docx
C:\Users\Test\Folder1\TUV.gif

After running script:

C:\Users\Test\001\ABC.xlsx
C:\Users\Test\002\QRS.pdf
C:\Users\Test\003\XYZ.docx
C:\Users\Test\Folder1\TUV.gif

Note: Names, extensions, and number of files will vary each time the script is run on a batch of files. The order in which files are placed into the new numbered subdirectories is not important, just that each subdirectory has a short, unique name. I have another script that will apply a consistent sequential naming convention for all subdirectories, but first I need to get all files into separate folders while maintaining their native file names.

This is where I'm at so far:

$id = 1
Get-ChildItem | where {!$_.PsIsContainer}| % {
MD ($_.root +($id++).tostring('000'));
MV $_ -Destination ($_.root +(001+n))
}

The MD expression successfully creates the subdirectories, but I not sure how to write the MV expression to actually move the files into them. I've written (001+n) to illustrate the concept I'm going for, where n would increment from 0 to the total number of files. Or perhaps an entirely different approach is needed.


Solution

  • $id = 1
    Get-ChildItem C:\Test\ -file  | % {
        New-Item -ItemType Directory -Path C:\Test -Name $id.tostring('000')
        Move-Item $_.FullName -Destination C:\Test\$($id.tostring('000'))
        $id++
    }
    

    Move-Item is what you were looking for.