Is this the best it can get?

DEREK CHUA 0 Reputation points
2025-11-11T00:25:35.2466667+00:00

Add-Type -AssemblyName System.Windows.Forms

$dictDialog = New-Object System.Windows.Forms.OpenFileDialog

$dictDialog.Title = "Select dictionary.txt"

$dictDialog.Filter = "All files (.)|."

$null = $dictDialog.ShowDialog()

$dictionaryPath = $dictDialog.FileName

$pseudoDialog = New-Object System.Windows.Forms.OpenFileDialog

$pseudoDialog.Title = "Select pseudonymized.txt"

$pseudoDialog.Filter = "All files (.)|."

$null = $pseudoDialog.ShowDialog()

$pseudonymPath = $pseudoDialog.FileName

$targetDialog = New-Object System.Windows.Forms.FolderBrowserDialog

$targetDialog.Description = "Select folder to scan"

$null = $targetDialog.ShowDialog()

$targetFolder = $targetDialog.SelectedPath

$outputDialog = New-Object System.Windows.Forms.FolderBrowserDialog

$outputDialog.Description = "Select output folder"

$null = $outputDialog.ShowDialog()

$outputFolder = $outputDialog.SelectedPath

$dictionary = Get-Content $dictionaryPath

$pseudonyms = Get-Content $pseudonymPath

$map = @{}

for ($i = 0; $i -lt $dictionary.Count; $i++) {

$map[$dictionary[$i]] = $pseudonyms[$i]

}

$changesLogPath = Join-Path $outputFolder "_Changes.txt"

if (Test-Path $changesLogPath) { Remove-Item $changesLogPath }

New-Item -ItemType File -Path $changesLogPath -Force | Out-Null

function Is-TextFile($path) {

try {

Get-Content $path -TotalCount 1 -ErrorAction Stop | Out-Null

return $true

} catch {

return $false

}

}

Get-ChildItem -Path $targetFolder -Recurse -File | Where-Object { Is-TextFile($_.FullName) } | ForEach-Object {

$filePath = $_.FullName

$relativePath = $filePath.Substring($targetFolder.Length).TrimStart('')

$outputPath = Join-Path $outputFolder $relativePath

$content = @(Get-Content $filePath)

$newContent = @($content)

$changes = @()

for ($i = 0; $i -lt $content.Count; $i++) {

$line = $content[$i]

$modified = $line

foreach ($key in $map.Keys) {

$modified = $modified -replace [regex]::Escape($key), $map[$key]

}

if ($line -ne $modified) {

$changes += "File: $filePathnOriginal: $linenModified: $modified`n"

}

$newContent[$i] = $modified

}

if ($changes.Count -gt 0) {

$outputDir = Split-Path $outputPath

if (!(Test-Path $outputDir)) {

New-Item -ItemType Directory -Path $outputDir -Force | Out-Null

}

$newContent | Set-Content $outputPath

Add-Content -Path $changesLogPath -Value ($changes -join "`n")

}

}

Get-ChildItem -Path $targetFolder -Recurse -Directory | Sort-Object -Property FullName -Descending | ForEach-Object {

$originalName = $_.Name

$newName = $originalName

foreach ($key in $map.Keys) {

$newName = $newName -replace [regex]::Escape($key), $map[$key]

}

if ($originalName -ne $newName) {

$parent = Split-Path $_.FullName -Parent

$newPath = Join-Path $parent $newName

Rename-Item -Path $_.FullName -NewName $newName

Add-Content -Path $changesLogPath -Value "Folder renamed:nOriginal: $($_.FullName)nNew: $newPath`n"

}

}

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

2 answers

Sort by: Most helpful
  1. Q&A Assist
    2025-11-11T00:25:46.6466667+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    The provided PowerShell script is a comprehensive solution for processing text files and renaming directories based on a mapping from a dictionary and pseudonyms. It includes functionality for:

    1. Selecting Input Files: It uses OpenFileDialog to allow users to select a dictionary file and a pseudonym file.
    2. Selecting Folders: It uses FolderBrowserDialog to select a target folder to scan and an output folder to save modified files.
    3. Reading and Mapping: It reads the contents of the dictionary and pseudonym files into arrays and creates a mapping between them.
    4. Processing Files: It recursively scans the target folder for text files, replaces occurrences of dictionary words with their corresponding pseudonyms, and logs changes.
    5. Renaming Directories: It also renames directories based on the same mapping and logs these changes.

    Overall, this script is well-structured and should work effectively for its intended purpose. However, there are always potential improvements or optimizations that can be made based on specific requirements or edge cases, such as handling large files more efficiently or adding error handling for file operations. If you have specific aspects you would like to improve or questions about the script, feel free to ask!

    0 comments No comments

  2. Domic Vo 11,700 Reputation points Independent Advisor
    2025-11-11T02:59:57.34+00:00

    Hello DEREK CHUA,

    You’ve already built a solid script that does a lot — from prompting for paths, mapping dictionaries, scanning files, replacing content, logging changes, and even renaming folders. Functionally it works well, but there are a few ways to make it cleaner, safer, and easier to maintain.

    Some quick wins include using clearer file filters in your dialogs, handling relative paths more reliably, optimizing replacements with a single regex pattern instead of looping through every key, and formatting logs with timestamps for easier review. Adding try/catch around file writes and renames will also make the script more resilient if something fails.

    Here are some of suggestions you could test:

    1. Cleaner filters in dialogs: powershell
         $dictDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*"
      
    2. Safer relative paths: powershell
         $relativePath = $filePath.Substring($targetFolder.Length).TrimStart('\')
      
    3. Optimized replacements: Build one regex pattern from all keys instead of looping: powershell
         $pattern = [string]::Join('|', $map.Keys | ForEach-Object { [regex]::Escape($_) })
      

    $modified = [regex]::Replace($line, $pattern, { $map[$args[0].Value] })

       
    1. **Improved logging**:
    
       powershell
       
       ```powershell
       Add-Content -Path $changesLogPath -Value ("[{0}] File: {1}`nOriginal: {2}`nModified: {3}`n" -f (Get-Date), $filePath, $line, $modified)
    
    1. Error handling on renames: powershell
         try {
          Rename-Item -Path $_.FullName -NewName $newName -ErrorAction Stop
      

    } catch { Add-Content -Path $changesLogPath -Value "Failed to rename folder: $($.FullName). Error: $" }

       
    If this guidance proves helpful, feel free to click “Accept Answer” so we know we’re heading in the right direction 😊. And of course, I’m here if you need further clarification or support. 
    
    Domic.
    
    
    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.