2014-05-31

Bulk File Extension Renamer - PowerShell

Here's a quick PowerShell script to change the extension on a group of matching files, posted chiefly to illustrate how much more concise PowerShell can be when compared to VBScript (I'll post an equivalent script shortly). The script below is still about twice the length of the a similar script I wrote in bash for *nix but it's certainly an improvement in both length and readability over VBS.

First up, grab the required parameters (old extension, new extension) from the command line. If either or both are missing, the user will be prompted to enter them.

Each parameter is set with three options -


[parameter(Mandatory = $true)] makes the parameter mandator.

ValidateNotNullorEmpty is called to do exactly what it says on the tin.
 

[string]$oldExt puts the value of the parameter into a string called $oldExt.

1:  param(  
2:       [parameter(Mandatory = $true)]  
3:       [ValidateNotNullOrEmpty()]  
4:       [string]$oldExt,  
5:       [parameter(Mandatory = $true)]  
6:       [ValidateNotNullOrEmpty()]  
7:       [string]$newExt  
8:  )
9:

Use Get-ChildItem to fill an array with files that have the old extension.

10:  $files = @(Get-ChildItem *.$oldExt)

If there is at least one filename in the array, loop through the array. Otherwise let the user know that there were no matches.

11:  if ($files.length -gt 0){
12:       foreach($file in $files){
13:              write-host "`nCurrent Name:" $file.Name
[ ... ]
32:  else {  
33:       write-host "No files with extension:" $oldExt`n -foregroundcolor "yellow"  
34:  }  


Create the new filename by combining the BaseName (original file sans extension) with the new extension (joined with a dot).

15:            $newName = $file.BaseName + "." + $newExt  
16:            write-host "New Name:" $newName  

Check if a file or directory with the new name already exists. Throw an error if so (in red, because *alarming*).
17:            if (Test-Path $newName) {  
18:                 write-host "Error: Can't rename" $file.Name "to" $newName "- a file with that name already exists`n" -foregroundcolor "red"  
19:            }  
20:            elseif ($file.Attributes -like "*ReadOnly*") {  
21:                 write-host "Cannot rename" $file.Name "- file is Read Only`n" -foregroundcolor "red"  
22:            }  
23:            elseif ($file.Attributes -like "*Directory*") {  
24:                 write-host "Not renaming" $file.Name "- it is a directory`n" -foregroundcolor "red"  
25:            } 

Otherwise rename the file and confirm with a happier green message.

26:            else {  
27:                 rename-item -path $file.Name -newname $newName  
28:                 write-host "File renamed`n" -foregroundcolor "green"  
29:            }  

And that's about that. Here's a screenshot of it in action:



Finally, for good measure, here's the complete listing:
1:  param(  
2:       [parameter(Mandatory = $true)]  
3:       [ValidateNotNullOrEmpty()]  
4:       [string]$oldExt,  
5:       [parameter(Mandatory = $true)]  
6:       [ValidateNotNullOrEmpty()]  
7:       [string]$newExt  
8:  )  
9:    
10:  $files = @(Get-ChildItem *.$oldExt)  
11:  if ($files.length -gt 0) {  
12:       write-host "`nFiles to be processed:" $files.length -foregroundcolor "yellow"  
13:       foreach($file in $files) {  
14:            write-host "`nCurrent Name:" $file.Name  
15:            $newName = $file.BaseName + "." + $newExt  
16:            write-host "New Name:" $newName  
17:            if (Test-Path $newName) {  
18:                 write-host "Error: Can't rename" $file.Name "to" $newName "- a file with that name already exists`n" -foregroundcolor "red"  
19:            }  
20:            elseif ($file.Attributes -like "*ReadOnly*") {  
21:                 write-host "Cannot rename" $file.Name "- file is Read Only`n" -foregroundcolor "red"  
22:            }  
23:            elseif ($file.Attributes -like "*Directory*") {  
24:                 write-host "Not renaming" $file.Name "- it is a directory`n" -foregroundcolor "red"  
25:            }  
26:            else {  
27:                 rename-item -path $file.Name -newname $newName  
28:                 write-host "File renamed`n" -foregroundcolor "green"  
29:            }  
30:       }  
31:  }  
32:  else {  
33:       write-host "No files with extension:" $oldExt`n -foregroundcolor "yellow"  
34:  }  

No comments:

Post a Comment