Testing Empty Folders with PowerShell
I’m betting that every once in a while you need to clean up a folder structure, perhaps even your own, and you want to be able to trim away empty folders. Although PowerShell’s Test-Path cmdlet can be used for testing if a folder exists, there isn’t a command to tell you if a folder is empty or not. For our purposes, we’ll assume that an empty folder is one with no subfolders or files.
Normally, I prefer to use cmdlets where possible, even though I’m using the dir alias for Get-ChildItem. I could even use the –File or –Directory parameter if I needed a more refined test. But because PowerShell is built on the .NET Framework, there may be situations where using native commands might make more sense. One reason might be performance. Let’s say I need to use the Count property to help determine if a folder is empty. Using Get-Childitem I can run a command like this:
This gives me a value of 2935 and using Measure-Command, I can tell it took 742 milliseconds. But the folder object also has a number of .NET methods that I can invoke, such as GetFileSystemInfos(). That was much, much faster. Cmdlets are nice and easy to use, but there is a tradeoff, often in performance. Most of the time it doesn't really matter. But this particular method also has an interesting side-effect in that it will also count hidden files. Here's what happens if I use Get-ChildItem. It doesn't show by default unless you use –Hidden. However, this will only show hidden files. But the method I was using works for everything: With this in mind, I can create a PowerShell expression to indicate if a folder is empty or not:
I'll get a result like this: By the way, this expression took 87 ms compared to the cmdlet approach, which took 168 ms.
If I wanted to list only empty folders, I could easily and quickly run a command like this:
These folders have no files or subfolders. With this is mind, I created a function called Test-IsEmpty.
By default, the function writes a custom object to the pipeline indicating if a folder is empty and if not how many child items it contains. This makes it easy to get only empty folders. Once I have this, information removing them is trivial. I also wrote the function to easily test a single folder.
There are other methods if you want to test for only the existence of subfolders or files if you need that level of granular control. It wouldn't take much to revise my function with the appropriate method. Finally, even though I am using a .NET method in my function, don't feel that you have to. There's nothing wrong with using out of the box cmdlets and there parameters. That is normally the approach I take when creating PowerShell tools. But if you feel up to it, and it meets a business need, there's nothing wrong with coloring outside of the lines.