Wednesday, June 30, 2010

Powershell: Add an extension to every file in a directory

It's been awhile since I've posted up a Powershell script.  Powershell really is great, and I really don't use it enough.  I should start using it all the time for any ridiculous thing I can think of just so I can polish up my skills so when that once in a blue moon, "holy crap! do something complicated quick!" situation comes up I'll be ready...

This time I downloaded a bunch of mp3s that were on Google docs.  Google docs is awesome, it lets you select a bunch of files, and download them all.  Then it zips them up so you can download them all together.  Unfortunately, when I unzipped them, they didn't have a file extension...
dir | % { mv $_.FullName ( $_.Name + ".mp3" ) }
That command gets every file in the directory ( dir ), sends them to the next command ( | ), which loops over them one at a time ( %, is short hand for foreach-object ), then executes the move command ( mv ) with the file's full name as the first argument ( $_.FullName, $_ is magically set to the current loop item ), and the file's name with .mp3 tacked onto the end as the second argument ( $_.Name + ".mp3" ).  The parentheses tell it to evaluate the expression and pass the result as the second argument.

Beautifully simple.

Need to figure out what properties are available on the objects you get from the dir command?
dir | get-member
Need to figure out what the value of one of those properties will actually be?
dir | % { $_.FullName }
Gotta love Powershell!


  1. My dad pointed out to me that in cmd you can do this by: rename *.* *.mp3.

    Oddly enough, you can't do this in powershell.

    I did find a slightly simpler powershell way to do this:
    dir | rename-item -newname { $ + '.mp3' }

    That's basicaly the same, but using rename you don't need the foreach-object command.

    1. I can't believe the answer to my problem comes from six years ago! Thanks lol

  2. Here's another fun example. I wanted to move all files that ended in Repository.cs to a Repositories folder in Mercurial:

    dir *Repository.cs | % { hg rename $_.Name ( ".\Repositories\" + $_Name ) }

  3. And another way. As mentioned above exploring PS to learn its power whenever I think to my self "I bet PS can do this with one command". Just discovered Powershell ISE. Wow.
    get-childItem "C:\Users\user1\Documents\closet*" | rename-item -newname { $ + ".txt" }


Note: Only a member of this blog may post a comment.