Rename folders based off of newest pdf in folder

54 Views Asked by At

I currently have 20000+ folders that where given a random string of characters when created. I would like to rename each folder with the name of the last PDF modified within each folder. I'm definitely in over my head. The current script seems to just move the PDF and/or folder without renaming it or creating a folder with the PDF name.

Get-ChildItem -Path $SourceFolder -Filter *.pdf |
 ForEach-Object {
     $ChildPath = Join-Path -Path $_.Name.Replace('.pdf','') -ChildPath $_.Name

     [System.IO.FileInfo]$Destination = Join-Path -Path $TargetFolder -ChildPath $ChildPat

     if( -not ( Test-Path -Path $Destination.Directory.FullName ) ){
         New-Item -ItemType Directory -Path $Destination.Directory.FullName
         }

     Copy-Item -Path $_.FullName -Destination $Destination.FullName
     }
1

There are 1 best solutions below

3
Rich Moss On

Welcome, Robert! There's a few things going on with your script:

  1. There's a typo: $ChildPat
  2. You don't need a FileInfo object to create the new directory, and you can't create one from a non-existent path. $Destination = Join-Path $_.Directory $_.BaseName will get the new folder name more reliably, in the unusual case where the file name has embedded '.pdf'
  3. It doesn't get the latest PDF.

Assuming you only want to get folders that have a PDF, you should have a nested Get-ChildItem for each folder, as @Lee_Dailey recommended:

Push-Location $SourceFolder
Foreach ($dir in (Get-ChildItem *.pdf -Recurse | Group-Object Directory | Select Name )){
        Push-Location $dir.Name
        $NewestPDF = Get-ChildItem *.pdf | Sort-Object ModifiedDate | Select -Last 1
        $Destination = Join-Path $dir.Name "..\$($NewestPDF.BaseName)"
        If(!(Test-Path $Destination)){New-Item $Destination -ItemType Directory}
        Copy-Item *.PDF $Destination 
        Pop-Location
        #Remove-Item $dir.Name #uncomment to remove the old folder (is it empty?)
}