[Solved] Script for renaming files in a specific way


As commented, it would be a lot simpler if you put the old and new ID values in a CSV file like this:

"OldID","NewID"
"12345","98765"
"23456","87654"
"34567","76543"

Then, something like below should work:

# read this CSV to get an array of PSObjects
$ids = Import-CSV -Path 'D:\ReplaceId.csv'

# build a lookup table from the $ids variable
$hash = @{}
$ids | ForEach-Object { $hash[$_.OldID] = $_.NewID }

# next, get a list of all files that have names starting with any 
# of the 5 digits from column 'OldID' and loop through
Get-ChildItem -Path 'THE PATH TO YOUR DIRECTORY' -Filter '*.pdf' -File | 
    Where-Object { $hash.Keys -contains $_.Name.Substring(0,5) } | 
    ForEach-Object {
        # get the value for the new ID from the lookup hashtable
        # and combine it with the remainder of the filename
        $newName="{0}{1}" -f $hash[$($_.Name.Substring(0,5))], $_.Name.Substring(5)
        $_ | Rename-Item -NewName $newName -WhatIf
    }

If the console info shows the correct replacement names, remove the -WhatIf switch to actually start renaming the files

If you add the -Recurse switch to the Get-ChildItem cmdlet, the code will also rename files inside any subfolder.


Update


Of course, the above assumes there is no mix of Old and New Id numbers in the folder. Since you commented that this is the case you will get file already exists errors.
To overcome that, you need to make sure the new filenames are unique inside the folder. You can do that for instance like this.

It appends an index number between brackets to the name if a file with that name already exists.

Get-ChildItem -Path 'D:\Test' -Filter '*.pdf' -File | 
    Where-Object { $hash.Keys -contains $_.Name.Substring(0,5) } | 
    ForEach-Object {
        # get the value for the new ID from the lookup hashtable
        # and combine it with the remainder of the filename
        $newId = $hash[$($_.Name.Substring(0,5))]
        $newName="{0}{1}" -f $newId, $_.Name.Substring(5)
        # since a filename with the new ID may already exist, 
        # you need to create a unique filename by appending an indexnumber
        $fullName = Join-Path -Path $_.DirectoryName -ChildPath $newName
        $index = 1
        while (Test-Path -Path $fullName -PathType Leaf) {
            $newName="{0}{1}({2}){3}" -f $newId, $_.BaseName.Substring(5), $index++, $_.Extension
            $fullName = Join-Path -Path $_.DirectoryName -ChildPath $newName
        }
        $_ | Rename-Item -NewName $newName -WhatIf
    }

Before:

D:\TEST
    12345_id_user.pdf
    12345_id_user2.pdf
    12345_id_user3.pdf
    23456_id_user.pdf
    34567_id_user.pdf
    34567_id_user2.pdf
    76543_id_user2.pdf
    98765_id_user.pdf

After:

D:\TEST
    76543_id_user.pdf
    76543_id_user2(1).pdf
    76543_id_user2.pdf
    87654_id_user.pdf
    98765_id_user(1).pdf
    98765_id_user.pdf
    98765_id_user2.pdf
    98765_id_user3.pdf

Or if you want to increase the index number you already seem to apply, use this:

Get-ChildItem -Path 'D:\Test' -Filter '*.pdf' -File | 
    Where-Object { $hash.Keys -contains $_.Name.Substring(0,5) } | 
    ForEach-Object {
        # get the value for the new ID from the lookup hashtable
        # and combine it with the remainder of the filename
        $newId    = $hash[$($_.Name.Substring(0,5))]
        $newName="{0}{1}" -f $newId, $_.Name.Substring(5)
        # since a filename with the new ID may already exist, 
        # you need to create a unique filename by incrementing the indexnumber

        # get the basename of the new name without any index numbers at the end
        $baseName  = [System.IO.Path]::GetFileNameWithoutExtension($newName) -replace '\d+$'
        $extension = $_.Extension
        # get an array of all file and folder names of items with a similar name already present in the folder
        $similar = @(Get-ChildItem $_.DirectoryName -Filter "$baseName*$extension" | Select-Object -ExpandProperty Name)
        $index = 1
        while ($similar -contains $newName) {
            $newName="{0}{1}{2}" -f $baseName, $index++, $extension
        }

        $_ | Rename-Item -NewName $newName -WhatIf
    }

Before:

D:\TEST
    12345_id_user.pdf
    12345_id_user2.pdf
    12345_id_user3.pdf
    23456_id_user.pdf
    34567_id_user.pdf
    34567_id_user2.pdf
    76543_id_user2.pdf
    98765_id_user.pdf

After:

D:\TEST
    76543_id_user.pdf
    76543_id_user1.pdf
    76543_id_user2.pdf
    87654_id_user.pdf
    98765_id_user.pdf
    98765_id_user1.pdf
    98765_id_user2.pdf
    98765_id_user3.pdf

5

solved Script for renaming files in a specific way