Use PowerShell to Easily Organize Your Music Collection

Summary: Microsoft Scripting Guy, Ed Wilson, teaches you how to use Windows PowerShell to organize your music collection for ease of playback on Windows.

Microsoft Scripting Guy, Ed Wilson, is here. I love the weekend. In general, it is a time for me to explore and to experiment with Windows PowerShell. These experimentation sessions quite often are purpose driven—I have some annoying problem that has finally reached a sufficient threshold of vexation to merit a few time slices of my day.

I enjoy playing music on my computer while I am writing. Often I listen to my Zune, but it is easier for me to use Windows Media player. There is little performance hit on my system because my music files are on a separate drive than my operating system or my Hey, Scripting Guy! data files. The problem with the manual method of playing music files is that the songs reside in dozens of individual, nested folders. This layout is shown in the image that follows.

Image of folder

For manual music operations, a better arrangement (at least for me) is to have all the songs in a single folder. With this arrangement, all I need to do is select the songs I want to listen to, and then I can select Play directly from Windows Explorer. This technique is shown in the following image.

Image of folder

The cool thing about Windows PowerShell is that I can fix annoying problems, such as the one I have with my music files, without the need to write a script. In fact, it is three commands to fix this issue. The first command sets my working location to the G:\music folder. The next command moves all of my music files to the root of the Music folder. I use the Get-ChildItem cmdlet (gci is the alias) to retrieve a listing of all the MP3 files in my Music folder. I use the Foreach-Object cmdlet (% is the alias) to move each file by using the Move-Item cmdlet (move is alias) to the root of my Music folder. Here is the command.

sl g:\music

gci -Filter *.mp3 -recurse | % {Move -Path $_.fullname -dest g:\music}

Note: For my particular application, this technique works just fine. If you have files outside of nested folders, you will need to add a check for the parent folder, or else the command will attempt to move the file to the location where the file already exists, and it generates errors.

If you are not certain what a command will actually do, make sure that you use the WhatIf parameter. Here is the command, revised to incorporate the WhatIf parameter.

gci -Filter *.mp3 -recurse | % {Move -Path $_.fullname -dest g:\music -whatif}

Now, I need to delete all the empty folders. To do this, I use two commands. The first command uses the Get-ChildItem (gci is alias) to find all of the child folders. I use the Recurse parameter to force the command to find folders and all subfolders. To identify a folder, I use the Where-Object (? is the alias) to find the Mode that begins with the letter d. Here is the first command to find all the folders.

$dir = gci g:\music -recurse | ? {$_.mode -match ‘^d’}

Now I need to find the folders that are empty. I pipe the collection of FolderInfo objects to the Where-Object (? is the alias), and I call the GetFiles method to see how many files exist in each folder. If there are no files, I pipe the object to the Remove-Item (del is the alias) cmdlet. Here is the second command.

$dir | ? { !($_.getfiles().count) } | del

Once again, if you are not certain as to what the command will accomplish, add the WhatIf parameter to the Remove-Item command. Here is the command that uses the WhatIf parameter.

$dir | ? { !($_.getfiles().count) } | del -whatif

Cool, I now have my music collection in a single folder, and I can use Windows Media player to play directly from within Windows Explorer. Sweet! Join me tomorrow when I will welcome Microsoft PowerShell MVP, Sean Kearney, as he begins a special week in Blueville. It is great stuff!!! See you!

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy