As the title suggests I am trying to create a Powershell script to rename multiple files. The script refers to a csv file which contains a string in a csv file "column A". If the result is true then I would like to rename the file from "Column B".
Ive managed to get my code to work based on a string but this is the next stage - can anyone help me please?
Current Code:
Get-ChildItem -Path C:\ -Recurse -ErrorAction SilentlyContinue |
Where {($_.Name -like "*blah*")} |
Rename-Item -NewName {[System.IO.Path]::GetFileNameWithoutExtension($_.fullname) ".BackupFile"}
Thanks as always!
CodePudding user response:
The following assumes that your CSV file contains the file names with extension - adjust as needed.
Build a hashtable from the CSV whose entries are keyed by
Column Avalues and each contain the correspondingColumn Bvalue.Filter the
Get-ChildItemoutput withWhere-Objectto only process files whose name is present as a key in the hashtable.- Note that switch
-Fileis added to theGet-ChildItemcall below, so as to process files only (not also directory objects).
- Note that switch
Rename each matching file to the value of the relevant hashtable entry.
# Build a hashtable from the CSV that with old-name-new-name pairs.
$ht = [ordered] @{} # Note: you can omit [ordered] in this case.
Import-Csv file.csv |
ForEach-Object { $ht[$_.'Column A'] = $_.'Column B' }
Get-ChildItem -Path C:\ -File -Recurse -ErrorAction SilentlyContinue |
Where-Object { $ht.Contains($_.Name) } |
Rename-Item -NewName { $ht[$_.Name] } -WhatIf
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.
Note: As an alternative to filtering Get-ChildItem output with Where-Object after the fact, you could use the former's -Include parameter as follows:
-Include $ht.Keys- However, up to at least PowerShell 7.2.x,
-Includeis actually slower than a post-filtering solution - see this answer.
