I'm an information pack rat. I use a computer for a while, and documents get full of all kinds of junk -- early drafts, versions that people sent me that I don't need anymore and the like. To make file and disk cleanup easier, I can leverage two Windows PowerShell cmdlets.
Remove-Item gets rid of the dross. Remove-Item is like the DOS Del command on steroids. Like Del, this cmdlet works for files, but it also works for other items such as certificates, folders or registry keys.
Get-ChildItem returns the items within the named item, like the current directory. Once it returns the items I want, it can pass the information to Remove-Item.
Someone who's organized might put all initial drafts into a junk folder and then move the approved versions to the production folders only when they were ready for prime time. If you organize your files like this, then keeping organized would be easy. Any time you wanted to get rid of the junk files, you could delete the junk folder and all its contents with it.
To do this with Remove-Item, just type the cmdlet, including the path of the folder as an argument. Here's an example that cleans out the junk folder where I keep scripts I'm experimenting with.
If junk is empty, then PowerShell will delete it with no questions asked. If it's not empty, Windows PowerShell shows that it's watching your back for you, like this:
The item at C:scriptsjunk has children and the Recurse parameter was not specified. If you continue, all children will be removed with the item. Are you sure you want to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
This is nice, because it gives me the chance to go check the contents of junk before I eliminate them for good. If I'm certain that everything I still want is out of junk, then I can just run the original command with the -recurse parameter and tell PowerShell to go ahead without further confirmation.
Just shoving all files into a junk folder until they're approved for the production folders isn't really the way I work, though. I'm more likely to want to delete all of a certain kind of file, or delete only files that have the word "draft" in the file name or are of a certain age. Remove-item makes it easy to selectively delete files with the -include and -exclude parameters.
Let's start by assuming that I want to get rid of only the files whose names include the word "draft" in all subfolders of a folder. To do this, I'll get all items using the Get-ChildItem cmdlet with its -include parameter to tell the cmdlet to ignore all items that don't have the word "draft" somewhere in their names -- hence the asterisks on each side of the word "draft." Then I'll pipe that output to Remove-Item. (Although the documentation tells you that you need the -include parameter, it's not required.)
That set of cmdlets could look like this:
get-childitem c:scripts *draft* -recurse | remove-item
That worked pretty well, so let's get a bit more destructive with our disk cleanup script. Upon looking through my folders, I realize that I don't really care about anything except Word07 and PowerPoint07 files. The command to delete everything else looks like this:
get-childitem c:scripts -exclude .docx, .pptx -recurse | remove-item
You can also combine the include and exclude parameters -- for example, to include all .txt files except those that have the word "final" somewhere in the name.
Are you sure you want to do that?
Easy, right? There are two catches. First, Remove-Item isn't specifically a file-removal cmdlet, it's an item-removing cmdlet. This makes it very flexible but also can have unexpected consequences. For example, if I choose to remove all items in a folder except for those with the .docx extension, then I will not only delete all those files, but also any folders below the folder in which I start the operation. Folders don't have a .txt extension.
Another catch is that any files (or other items) that you delete will be gone. This behavior is different from deleting files from Explorer. Delete a file from Explorer, and it goes into the Recycle bin where you can undelete it. Delete a file with Remove-Item, and it bypasses the Recycle bin and goes straight to The Land Where Files are Eternally Blessed. So if you're using Windows PowerShell to do batch deletions, then you'd better be pretty sure of what you're doing. This goes double if you distribute your folder-cleanup tip to others.
Luckily, you don't have to do much to make the disk cleanup script a bit more foolproof. As we saw earlier, Remove-Item will warn you before allowing you to delete a folder with files or folders in it, unless you run it with the -recurse switch. Windows PowerShell also has two other parameters that aren't specific to deleting items that you can use whenever a cmdlet has potentially dangerous consequences: -whatif shows you the results of running a cmdlet, and -confirm asks you to confirm the action.
For example, at one point when playing with the -include and -exclude parameters to Remove-Item, I reversed them in a way that would have destroyed the folder structure of Documents and all the files within that structure. Because I had used the -whatif parameter with the command, I was able to see what was going to happen before I executed the command, giving me a chance to fix the command.
More on Windows PowerShell
- Learn more about Windows PowerShell.
- Learn how to get process information with Windows PowerShell.
- Visit our Windows PowerShell topical resource center.
About the Author: Christa Anderson is the author of Windows Terminal Servicesand The Definitive Guide to MetaFrame XP. She is also co-author of the book Mastering Windows 2003 Server.