PowerShell Script to Batch Rename Files with Parent Directory Name Pattern in Windows


4 views

When dealing with hundreds of image files in a directory like family_pics, manually renaming each file to follow a consistent pattern becomes tedious. The goal is to transform filenames like img123.jpg into family_pics_1.jpg while preserving file extensions.

Windows PowerShell provides powerful file manipulation features through the Get-ChildItem cmdlet and pipeline operations. Here's a complete solution that handles:

  • Directory name extraction
  • Sequential numbering
  • Extension preservation
  • Recursive processing
$directory = "C:\\family_pics"
$files = Get-ChildItem -Path $directory -File -Recurse
$counter = 1

foreach ($file in $files) {
    $newName = "{0}_{1}{2}" -f $file.Directory.Name, $counter++, $file.Extension
    Rename-Item -Path $file.FullName -NewName $newName
}

For production use, we should add validation and duplicate handling:

param(
    [string]$Path = (Get-Location).Path,
    [switch]$Recursive = $false,
    [string]$Prefix = ""
)

try {
    $options = @{File = $true}
    if ($Recursive) { $options.Recurse = $true }

    $files = Get-ChildItem -Path $Path @options | 
             Where-Object { $_.Name -notlike "$($_.Directory.Name)_*" }

    $counter = 1
    foreach ($file in $files) {
        $baseName = if ($Prefix) { $Prefix } else { $file.Directory.Name }
        $newName = "{0}_{1}{2}" -f $baseName, $counter++, $file.Extension
        $newPath = Join-Path $file.Directory.FullName $newName
        
        if (Test-Path $newPath) {
            Write-Warning "Skipping duplicate: $newName"
            continue
        }
        
        Rename-Item -Path $file.FullName -NewName $newName -Force
    }
}
catch {
    Write-Error "Renaming failed: $_"
}

Run the script in different ways:

# Basic usage
.\RenameFiles.ps1 -Path "C:\\family_pics"

# With custom prefix
.\RenameFiles.ps1 -Path "C:\\vacation_photos" -Prefix "summer2023"

# Recursive processing
.\RenameFiles.ps1 -Path "C:\\projects" -Recursive

For simple cases, you can use Command Prompt:

@echo off
setlocal enabledelayedexpansion
set count=1
for %%f in (*.jpg) do (
    ren "%%f" "family_pics_!count!.jpg"
    set /a count+=1
)

Every developer encounters situations where they need to standardize file names across directories. The manual approach becomes tedious when dealing with:

  • Hundreds of files in nested folders
  • Different file extensions mixed in the same directory
  • Need to maintain original file order during renaming

Windows PowerShell provides robust file system manipulation capabilities. Here's why it's perfect for this task:

# Basic rename operation demonstration
Get-ChildItem -Path "C:\family_pics\*.jpg" | 
Rename-Item -NewName {"family_pics_$($_.BaseName.Split('img')[1]).jpg"}

This script handles all requirements:


function Rename-FilesRecursive {
    param (
        [string]$rootPath = (Get-Location).Path,
        [switch]$preview
    )
    
    $files = Get-ChildItem -Path $rootPath -File -Recurse
    
    foreach ($file in $files) {
        $dirName = $file.Directory.Name
        $counter = 1
        
        $newName = "{0}_{1}{2}" -f $dirName, $counter, $file.Extension
        
        while (Test-Path -Path (Join-Path -Path $file.Directory.FullName -ChildPath $newName)) {
            $counter++
            $newName = "{0}_{1}{2}" -f $dirName, $counter, $file.Extension
        }
        
        if ($preview) {
            Write-Host "Would rename: $($file.Name) -> $newName"
        } else {
            Rename-Item -Path $file.FullName -NewName $newName
        }
    }
}

# Usage examples:
# Rename-FilesRecursive -rootPath "C:\family_pics"
# Rename-FilesRecursive -rootPath "C:\projects" -preview

For production-grade solutions, you might want to add:


# Parallel processing for large directories
$files | ForEach-Object -Parallel {
    # Renaming logic here
} -ThrottleLimit 5

# Extension filtering
Get-ChildItem -Include *.jpg,*.png -Recurse

# Progress reporting
Write-Progress -Activity "Renaming Files" -Status "Processing..."

For those preferring other methods:

  • CMD Batch: for /r %i in (*) do @echo "%~nxi"
  • Python Script: Using os.walk() and shutil.move()
  • Third-party Tools: Bulk Rename Utility, Advanced Renamer

Always implement safeguards:


# Dry run first
Rename-FilesRecursive -preview

# Create backups
Copy-Item -Path $file.FullName -Destination "\\backup\$($file.Name)"