powershellpdfdirectory

Mass saving PDFs (with unique ID at the start of the PDF) to folders that have unique ID at the end


I've tried to figure out this one and searched far and wide to see if others have found a previous solution but couldnt find anything. I'm fairly new to powershell so please bare with me.

I have hundreds of files that are titled similarly, with the unique ID being at the beginning of the title: unique ID_2024 Details.pdf. I want to move the PDF files in this directory C:\F\2024 Detailed Letters to the individual folders in this folder C\:F\Individual Folders\XXX_XXXX [unique ID]. The unique ID contains 8 characters.

There are thousands of folders in the individual folders folder, so each letter would need to be sent to the folder with the unique id at the end.

I'm having trouble using Substring as I haven't been able to figure out how to match the unique ID at the beginning of the PDF name to the unique ID at the end of the folder title. I do not have the option to rename the folders or files.

Thank you!

$FilesToMove = 'C:\F\2024 Detailed Letters'
$TargetPath = 'C\:F\Individual Folders'

$Files = Get-ChildItem -Path $FilesToMove -File

foreach ($File in $Files) {
    $PathToMove = Get-ChildItem -Path $TargetPath -Directory -Filter "$(($File.Basename).Substring(0,8))*" | Select-Object -First 1
    Write-Output "Moving File $File to $PathToMove"
    Move-Item -Path $File.FullName -Destination "$($PathToMove.Fullname)\$($File.Name)"
}

Solution

  • Granted the unique IDs are truly unique and won't match with anything else in other folder names I think this should do. Try this with a test batch first though :)

    This will take the first 8 characters of your input filename and find a folder that has a name containing the unique ID (Not folders explicitly ending in the unique ID though - I am too lazy to find the regex right now to be 100% precise, sorry)

    $FilesToMove = 'C:\F\2024 Detailed Letters'
    $TargetPath = 'C:\F\Individual Folders'
    
    $Files = Get-ChildItem -Path $FilesToMove -File
    $DestinationFolders = Get-ChildItem -Path $TargetPath -Directory
    
    foreach ($File in $Files) {
        $DestinationFolderPath = $null
        foreach($Folder in $DestinationFolders){
            if($Folder.Name -match "$(($File.Basename).Substring(0,8))"){
                $DestinationFolderPath = $Folder.FullName
            }
        }
        if($DestinationFolderPath){
            Write-Output "Moving File $($File.Name) to $DestinationFolderPath"
            Move-Item -Path $File.FullName -Destination $DestinationFolderPath
        }else{
            Write-Host "Could not find destination folder for $($File.Name)"
        }
    }
    

    Looks like you were on the right track. I'm only just now figuring out how the filters work. For speed it is better to separate out the Get-ChildItem for the destination folders and then work with that object rather than re-run that command for each file you are processing. Then it doesn't have to scan thousands of folders each time. Hope this helps :) cheers