Search code examples
powershellpdfsubdirectorybatch-rename

Rename files with foldername and exclusions using powershell


There are lots of topics with the same title, but trying/mending them all to fit my needs is so far unsuccessful.

This came close to what I want to achieve, but the exclude is not working, it renames the PDF files in all subfolders instead of the only remaining folder “Folder 3”. Also here I tried solutions from other topics of which none worked for me so far.

[string[]]$Path = @('C:\test\')
[string[]]$Excludes = @('*folder 1*', '*Folder 2*')
Get-ChildItem $Path -Filter *.pdf -Recurse | ?{$_.DirectoryName -notlike $Excludes } | Rename-Item -NewName { $_.Directory.Parent.BaseName + '-' + $_.Name }

What I am trying to achieve is renaming all PDF files in a subfolder of a subfolder with the name of the first subfolder, see structure below.

C:\test\2704814
\Folder 1
|- file1.pdf
|- file2.pdf
\Folder 2
|- file1.pdf
|- file2.pdf
\Folder 3
|- file1.pdf
|- file2.pdf
C:\test\2704815
\Folder 1
|- file1.pdf
|- file2.pdf
\Folder 2
|- file1.pdf
|- file2.pdf
\Folder 3
|- file1.pdf
|- file2.pdf

etc.

To get this:

C:\test\2704814\Folder 3\2704814-file1.pdf

and

C:\test\2704814\Folder 3\2704814-file2.pdf

etc.


Solution

  • EDIT inserted another $ExcludeL1 for firstlevel subfolders

    The safest way is to do it step by step:

    • iterate the sub folders of test, store the name in a var
    • iterate the sub sub folders and exclude unwanted ( -notin requires the excludes to be literal)
    • iterate the pdf in there and check that they are not already prefixed with stored folder name.
    • finally rename.

    $Base = 'C:\test\'
    $ExcludeL1 = @('folder 1', 'Folder 2')
    $ExcludeL2 = @('Othername')
    
    Get-ChildITem -Path $Base -Directory | Where {$_.Name -notin $ExcludeL1}|ForEach {
      $PreFix = $_.Name
      Get-ChildItem -Path $_.FullName -Directory | 
        Where-Object {$_.Name -notin $ExcludeL2 } |
          ForEach-Object {
            Get-ChildItem $_.FullName -Filter *.PDF |
              Where-Object {$_.BaseName -notmatch $PreFix}|
                Rename-Item -NewName { "$PreFix-$($_.Name)"} -WhatIf
          }
    }
    

    If your output looks OK, remove the -WhatIf in the last line.

    Sample resutlt on my ramdrive A:

    > tree /F
    A:.
     └───test
        ├───2704814
        │   ├───Folder 1
        │   │       file1.pdf
        │   │       file2.pdf
        │   ├───Folder 2
        │   │       file1.pdf
        │   │       file2.pdf
        │   └───Folder 3
        │           2704814-file1.pdf
        │           2704814-file2.pdf
        └───2704815
            ├───Folder 1
            │       file1.pdf
            │       file2.pdf
            ├───Folder 2
            │       file1.pdf
            │       file2.pdf
            └───Folder 3
                    2704815-file1.pdf
                    2704815-file2.pdf