To run this or any other PowerShell script, you'll have to read up on the Get-Executionpolicy and Set-Executionpolicy as PowerShell disables scripts by default.
My previous article explained how to clean the extra "stuff" added to music file names. This article further cleans those file names, gets rid of the troublesome [brackets], then uses the Genre, Artist, and Album information to create a new folder structure on your desktop. You can then move it to wherever you store your music.
Here is an example of some files my friend wanted help managing:
Notice the brackets, curly brackets, and other special characters in the file names and properties.
This is the same folder of music files after running the script:
I performed a search for all files to display the name changes. Notice the subfolder structure that each file is located in. The left side is the Genre structure created based on the file information.Three more notes before going through the script:
- The script automatically ignores subfolders. I strongly recommend you perform this move one folder at a time so you can ensure it worked properly.
- The script will process any type of file. You'll have to create an -exclude in the top $filename variable if you want it to ignore JPG's, AVI's, and etc.
- Do not save this script to the folder you are processing. It will be moved into the Music folder and could cause problems.
## Start of Script
#We call the Shell Object
$shell = new-object -com shell.application
#Organized Music Folder Location
#You can change the location. The Music Root Folder defaults to your desktop
$MusicFolder = ($home + '\desktop\music')
#remove brackets from filenames per PowerShells bug with brackets
gci .\* |?{(!($_.psiscontainer))}|foreach{move -literalpath $_ ($_.name -replace ('\[|]','~'))}
#Set directory and file variables. Add -exclude to the Get-Item if you want
#to ignore other filetypes
#For instance: (get-item .\* -exclude *.avi,*.jpg)
$dirname = (get-item .\).fullname
$filename = (get-item .\*)|?{(!($_.psiscontainer))}|foreach-object{$_.name}
foreach($file in $filename){
#original filename holder, then split it to capture the extension and name only.
$fileholder = $file
$ext = ('.' + ($file.split('.')[-1]))
$noext = $file.trimend($ext)
#get Title (item number 21) property from the file
$shellfolder = $shell.namespace($dirname).parsename($file)
$title = $shell.namespace($dirname).getdetailsof($shellfolder,21)
#PowerShell filename bug for brackets.
#If there's a bracket in the title, $title will equal nul
if ($title -like "*``[*" -or $title -like "*``]*"){$title = $nul}
#if the title isn't empty, replace the filename with it
if ($title -gt 0){$file = ($title + $ext)}
#clean extraneous characters from the filename
#BTW, let me know if you have a better way to filter files
#for now, I borrowed this filter technique:
$file2 = $file -replace ('^[0-100]','')
$file3 = $file2 -replace ('.mp33','.mp3')
$file4 = $file3 -replace (' - ','-')
$file5 = $file4 -replace (' ',' ')
$file6 = $file5 -replace (' ',' ')
$file7 = $file6 -replace ('\(','')
$file8 = $file7 -replace (':','')
$file9 = $file8 -replace ('\)','')
$file10 = $file9 -replace ('\/','')
$file11 = $file10 -replace ('\>','')
$file12 = $file11 -replace ('\<','')
#Split the filename at the hyphen and only keep the last portion
#since that's normally the song name
$file13 = $file12.split('-')[-1]
$finalfilename = $file13
#rename the file after all the modifications
ren -erroraction silentlycontinue -path ($dirname + '\' + $fileholder) -newname $finalfilename
$shellfolder = $shell.namespace($dirname).parsename($finalfilename)
#Filtering for Artist - Items 13 and 217
$contribartist = $shell.namespace($dirname).getdetailsof($shellfolder,13)
$albumartist = $shell.namespace($dirname).getdetailsof($shellfolder,217)
#filtering the Album Name - Item 14
$album = $shell.namespace($dirname).getdetailsof($shellfolder,14)
$album1 = $album -replace ('^[0-100]','')
$album2 = $album1 -replace ('.mp33','.mp3')
$album3 = $album2 -replace (' - ','-')
$album4 = $album3 -replace (' ',' ')
$album5 = $album4 -replace (' ',' ')
$album6 = $album5 -replace ('\(','')
$album7 = $album6 -replace (':','')
$album8 = $album7 -replace ('\)','')
$album9 = $album8 -replace ('\/','')
$album10 = $album9 -replace ('\>','')
$album11 = $album10 -replace ('\<','')
$finalalbumname = $album11
#filtering the genre name - Item 16
$genre = $shell.namespace($dirname).getdetailsof($shellfolder,16)
$genre1 = $genre -replace ('^[0-100]','')
$genre2 = $genre1 -replace ('.mp33','.mp3')
$genre3 = $genre2 -replace (' - ','-')
$genre4 = $genre3 -replace (' ',' ')
$genre5 = $genre4 -replace (' ',' ')
$genre6 = $genre5 -replace ('\(','')
$genre7 = $genre6 -replace (':','')
$genre8 = $genre7 -replace ('\)','')
$genre9 = $genre8 -replace ('\/','')
$genre10 = $genre9 -replace ('\>','')
$genre11 = $genre10 -replace ('\<','')
$finalgenrename = $genre11
#Deciding between Album and Contributing artist then cleaning the name
$artist = if ($contribartist -gt 0){$contribartist}else{$albumartist}
$artist1 = $artist -replace ('^[0-100]','')
$artist2 = $artist1 -replace ('.mp33','.mp3')
$artist3 = $artist2 -replace (' - ','-')
$artist4 = $artist3 -replace (' ',' ')
$artist5 = $artist4 -replace (' ',' ')
$artist6 = $artist5 -replace ('\(','')
$artist7 = $artist6 -replace (':','')
$artist8 = $artist7 -replace ('\)','')
$artist9 = $artist8 -replace ('\/','')
$artist10 = $artist9 -replace ('\>','')
$artist11 = $artist10 -replace ('\<','')
$finalartistname = $artist11
$filetrim = $finalfilename.trimend($ext)
$filedupeinsert = ($filetrim + 'DUPE')
$filedupe = ($filedupeinsert + $ext)
#move file based on its Genre, Artist, and Album
#Replacing Brackets for tildes
if ($finalgenrename -like "*``[*" -or $finalgenrename -like "*``]*"){$finalgenrename -replace ('\[|]','~')}
if ($finalalbumname -like "*``[*" -or $finalalbumname -like "*``]*"){$finalalbumname -replace ('\[|]','~')}
if ($finalartistname -like "*``[*" -or $finalartistname -like "*``]*"){$finalartistname -replace ('\[|]','~')}
#moving songs to folders
#If there's no Genre entry, a default is used
#For the sake of endless genre possibilities, I used this filter to group
#the various types. Manipulate as you see fit:
if ($finalgenrename -like "*Rock*"){$finalgenrename = "Rock"}
if ($finalgenrename -like "*Alt*"){$finalgenrename = "Alternative"}
if ($finalgenrename -like "*Metal*"){$finalgenrename = "Metal"}
if ($finalgenrename -like "*Pop*"){$finalgenrename = "Pop"}
if ($finalgenrename -like "*Rap*"){$finalgenrename = "Rap"}
if ($finalgenrename -like "*Hip*"){$finalgenrename = "Hip-Hop"}
if ($finalgenrename -like "*R&B*"){$finalgenrename = "R&B"}
if (!($finalgenrename -gt 0)){$finalgenrename = "Genre"}
#If there's no Album entry, a default is used
if (!($finalalbumname -gt 0)){$finalalbumname = "Album"}
#Creating the desktop\music folder structure
#and moving files to their new folders
if (!(dir $MusicFolder\$finalgenrename -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename -force}
if (!(dir $MusicFolder\$finalgenrename\$finalartistname -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename\$finalartistname -force}
if (!(dir $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname -erroraction silentlycontinue)){md $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname -force}
if (dir $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$finalfilename -erroraction silentlycontinue){move -erroraction silentlycontinue ($dirname + '\' + $finalfilename) -destination $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$filedupe}else{move -erroraction silentlycontinue ($dirname + '\' + $finalfilename) $MusicFolder\$finalgenrename\$finalartistname\$finalalbumname\$finalfilename -force}
}
## End of Script