Rename my files

DEREK CHUA 0 Reputation points
2025-11-24T01:22:03.3733333+00:00

see my script

Add-Type -AssemblyName System.Windows.Forms
# --- Helper functions ---
function Select-FolderDialog {
    $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
    if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        return $dialog.SelectedPath
    }
    return $null
}
function Select-FileDialog {
    param([string]$title)
    $dialog = New-Object System.Windows.Forms.OpenFileDialog
    $dialog.Title = $title
    $dialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
    if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
        return $dialog.FileName
    }
    return $null
}
# --- Prompt user for inputs ---
$rootFolder = Select-FolderDialog
if (-not $rootFolder) { Write-Host "No folder selected. Exiting."; exit }
$dictFile   = Select-FileDialog -title "Select dictionary.txt"
$pseudoFile = Select-FileDialog -title "Select pseudo.txt"
if (-not $dictFile -or -not $pseudoFile) {
    Write-Host "Missing dictionary or pseudo file. Exiting."
    exit
}
# --- Load dictionary and pseudo lists into memory (trimmed) ---
$dict   = Get-Content $dictFile   | ForEach-Object { $_.Trim() }
$pseudo = Get-Content $pseudoFile | ForEach-Object { $_.Trim() }
if ($dict.Count -ne $pseudo.Count) {
    Write-Host "Dictionary and pseudo files must have the same number of lines."
    exit
}
# Build mapping table in memory
$map = @{}
for ($i=0; $i -lt $dict.Count; $i++) {
    $map[$dict[$i].ToLower()] = $pseudo[$i]
}
Write-Host "Starting scan in $rootFolder..."
Write-Host "Loaded $($map.Count) mappings into memory."
# --- Prepare log file ---
$logFile = Join-Path $rootFolder "Renamed_Output.txt"
"Type`tOriginal`tNew" | Out-File $logFile
# --- Function to replace words in a name ---
function Replace-WordsInName {
    param([string]$name)
    # Split name into words by non-alphanumeric boundaries
    $words = $name -split '([^A-Za-z0-9]+)'  # keeps delimiters
    for ($i=0; $i -lt $words.Count; $i++) {
        $word = $words[$i]
        if ($map.ContainsKey($word.ToLower())) {
            $words[$i] = $map[$word.ToLower()]
        }
    }
    # Recombine words
    return ($words -join "")
}
# --- Recursive function to process folders and files ---
function Process-Folder {
    param([string]$folderPath)
    # Process files
    Get-ChildItem -Path $folderPath -File | ForEach-Object {
        $fileName = $_.Name
        $newName  = Replace-WordsInName $fileName
        if ($newName -ne $fileName) {
            try {
                Rename-Item -Path $_.FullName -NewName $newName -ErrorAction Stop
                $newPath = Join-Path $_.DirectoryName $newName
                Write-Host "Renamed file: $($_.FullName) -> $newPath"
                "File`t$($_.FullName)`t$newPath" | Out-File $logFile -Append
            } catch {
                Write-Warning "Failed to rename file $($_.FullName): $_"
            }
        }
    }
    # Process subfolders
    Get-ChildItem -Path $folderPath -Directory | ForEach-Object {
        $subFolder = $_
        $folderName = $subFolder.Name
        $newName    = Replace-WordsInName $folderName
        if ($newName -ne $folderName) {
            try {
                Rename-Item -Path $subFolder.FullName -NewName $newName -ErrorAction Stop
                $newPath = Join-Path $subFolder.Parent.FullName $newName
                Write-Host "Renamed folder: $($subFolder.FullName) -> $newPath"
                "Folder`t$($subFolder.FullName)`t$newPath" | Out-File $logFile -Append
                $subFolder = Get-Item $newPath
            } catch {
                Write-Warning "Failed to rename folder $($subFolder.FullName): $_"
            }
        }
        # Recurse
        Process-Folder -folderPath $subFolder.FullName
    }
}
# --- Start recursive processing ---
Process-Folder -folderPath $rootFolder
Write-Host "Processing complete. Log saved to $logFile"

Windows for business | Windows Server | User experience | PowerShell
{count} votes

1 answer

Sort by: Most helpful
  1. Quinnie Quoc 7,400 Reputation points Independent Advisor
    2025-11-24T08:12:12.4666667+00:00

    Hello DEREK CHUA,

    Thank you for sharing your script. It is well-structured and functional, but there are a few ways you can simplify it without losing functionality:

    • Combine helper functions: Instead of separate Select-FolderDialog and Select-FileDialog, you can create one generic dialog function that accepts parameters for type and filter.
    • Use pipeline operations: For building the mapping table, you can use ForEach-Object directly with Get-Content to avoid the explicit for loop.
    • Inline replacement logic: The Replace-WordsInName function can be shortened by using -replace with a regex and a script block, though your current approach is clearer.
    • Recursive folder processing: You can use Get-ChildItem -Recurse with -File and -Directory filters to avoid writing a custom recursive function.
    • Logging: Instead of multiple Out-File calls, you can collect results in an array and export them once at the end.

    These changes can reduce the overall length of the script while keeping it maintainable. If this guidance helps, please click “Accept Answer” so others can benefit too. I’d be happy to provide a shortened sample if you’d like to see it in practice.

    Best regards,

    QQ.

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.