To improve and shorten your PowerShell script, you can consider the following suggestions:
- Consolidate File Dialogs: You can create a function to handle the file and folder selection dialogs to avoid repeating similar code for each dialog.
- Use
ForEach-Objectfor Hashtable Creation: Instead of using aforloop to create the hashtable, you can useForEach-Objectto make it more concise. - Combine File Operations: You can combine the operations that check for the existence of the output directory and create it into a single command using
New-Item -Force. - Optimize the Log Writing: Instead of checking for changes and writing to the log file in multiple places, consider collecting all changes and writing them at once after processing all files.
- Use
-replacewith a single command: You can use a single-replacecommand with a loop to handle all replacements in one go, which can simplify the logic.
Here’s a revised version of your script incorporating these suggestions:
Add-Type -AssemblyName System.Windows.Forms
function Select-FileOrFolder($dialogType, $title, $filter = '') {
if ($dialogType -eq 'File') {
$dialog = New-Object System.Windows.Forms.OpenFileDialog
$dialog.Title = $title
$dialog.Filter = $filter
$dialog.ShowDialog() | Out-Null
return $dialog.FileName
} else {
$dialog = New-Object System.Windows.Forms.FolderBrowserDialog
$dialog.Description = $title
$dialog.ShowDialog() | Out-Null
return $dialog.SelectedPath
}
}
$dictionaryPath = Select-FileOrFolder 'File' 'Select Dictionary File' 'Text files (*.txt)|*.txt|All files (*.*)|*.*'
$pseudonymPath = Select-FileOrFolder 'File' 'Select Pseudonym File' 'Text files (*.txt)|*.txt|All files (*.*)|*.*'
$targetFolder = Select-FileOrFolder 'Folder' 'Select Folder for Scanning'
$outputFolder = Select-FileOrFolder 'Folder' 'Select Scan Output Folder'
Write-Host "Dictionary Path: $dictionaryPath"
Write-Host "Pseudonym Path: $pseudonymPath"
Write-Host "Target Folder: $targetFolder"
Write-Host "Output Folder: $outputFolder"
$dictionary = Get-Content $dictionaryPath
$pseudonyms = Get-Content $pseudonymPath
$map = @{}
$dictionary | ForEach-Object { $map[$_] = $pseudonyms[$dictionary.IndexOf($_)] }
New-Item -ItemType Directory -Path $outputFolder -Force | Out-Null
$changesLogPath = Join-Path $targetFolder "changes.txt"
Remove-Item $changesLogPath -ErrorAction SilentlyContinue
New-Item -ItemType File -Path $changesLogPath -Force | Out-Null
Get-ChildItem -Path $targetFolder -Recurse -Filter *.log | ForEach-Object {
$fileContent = Get-Content $_.FullName
$newContent = $fileContent -replace ([regex]::Escape($map.Keys -join '|')), { $map[$_]}
$changes = Compare-Object -ReferenceObject $fileContent -DifferenceObject $newContent
if ($changes) {
$changes | ForEach-Object { Add-Content -Path $changesLogPath -Value "File: $($_.InputObject)`nOriginal: $($_.InputObject)`nModified: $newContent`n" }
}
$outputPath = Join-Path $outputFolder ($_.FullName.Substring($targetFolder.Length))
New-Item -ItemType Directory -Path (Split-Path $outputPath) -Force | Out-Null
$newContent | Set-Content $outputPath
}
This version is more concise and maintains the same functionality as your original script.