How to Delete Empty Folders in PowerShell
-
Get-ChildItem
Cmdlet in PowerShell -
Where-Object
Cmdlet in PowerShell - Delete Items From a Collection in PowerShell
- Conclusion
Effective directory management is essential in PowerShell scripting, and the Get-ChildItem
cmdlet serves as a cornerstone for navigating file systems. When tasked with cleaning up empty folders, traversing folder hierarchies becomes crucial.
This article delves into the practical usage of Get-ChildItem
alongside other cmdlets to systematically identify and remove empty directories within specified paths. By leveraging PowerShell’s powerful scripting capabilities, users can efficiently manage directories, ensuring a well-organized file system.
Get-ChildItem
Cmdlet in PowerShell
The Get-ChildItem
cmdlet retrieves all the child items (files and folders) for a specified location. When there is a need to delete all the empty folders in a given folder path, it is a must to traverse the folder hierarchy.
Hence, the Get-ChildItem
cmdlet would be helpful. This cmdlet accepts parameters like Recurse
and Directory
to fetch directory-type child items and recursively traverse the folder structure.
Syntax:
Get-ChildItem -Path -Directory -Recurse
There are many more optional parameters available to use. Let’s create a folder structure as shown in the following.
somepath/testA
testB
testD
testE
a.txt
testC
testF
b.txt
testG
testH
The purpose is to remove all the empty folders within the testA
folder. Therefore, the following folders should be deleted.
testD
testG
testH
Let’s fetch all the subdirectories in the given folder path (somepath/testA
).
$path = "D:\testA"
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
In this snippet, we assign the variable $path
the directory path "D:\testA"
, and we use the Get-ChildItem
cmdlet with the -Directory
and -Recurse
parameters to fetch all directories recursively from the specified path. The resulting list of directories is stored in the variable $fetchedDirList
, giving us a collection of directory objects that represent all directories within "D:\testA"
and its subdirectories.
Using the alias gci
instead of Get-ChildItem
is possible.
$fetchedDirList = gci $path -directory -Recurse
Transitioning from the original code to this revised version, we continue to capture the directory objects retrieved using the Get-ChildItem
cmdlet in the variable $fetchedDirList
. However, in this updated code, we utilize the alias gci
instead of the full cmdlet name Get-ChildItem
.
This shorthand maintains the functionality of fetching directories recursively from the specified path $path
and storing them in $fetchedDirList
.
Let’s check the $fetchedDirList
variable.
$fetchedDirList
Output:
All the directories and subdirectories have been fetched as expected.
Where-Object
Cmdlet in PowerShell
We need to filter out the empty directories from the above result. The Where-Object
cmdlet filters objects from a collection based on their properties.
The Where
alias can be used instead of the Where-Object
command. We need to filter the above directory list based on the item count within each directory.
The condition is shown in the following.
where { (gci $_.fullName).count -eq 0 }
When the given object from the collection has 0 sub-items, it is considered an empty directory. Hence, we should delete it.
Let’s pipe the previous step output to the Where
cmdlet.
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
In this line of code, we assign the variable $emptyDirectoryList
the result of filtering directories from $fetchedDirList
using the Where
alias. The filtering condition, defined within a script block, checks if the count of child items within each directory (retrieved using gci $_.FullName
) is equal to 0.
This approach effectively identifies and captures only the directory objects representing empty directories in $emptyDirectoryList
.
Let’s print the $emptyDirectoryList
.
$emptyDirectoryList
Output:
The result is perfectly correct. We got only two folders called testD
and testH
with empty content.
We can easily delete each object from the $emptyDirectoryList
collection. The Remove-Item
cmdlet can be used to delete an item.
Before that, we need to fetch the full path of each of the objects inside the $emptyDirectoryList
. The Select-Object
cmdlet can fetch the objects with its FullName
property.
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
In this line of code, we create a new variable $finalListToRemove
by extracting the full paths of the directories stored in $emptyDirectoryList
. We utilize the Select-Object
cmdlet with the -ExpandProperty FullName
parameter, allowing us to retrieve the value of the FullName
property for each directory object in $emptyDirectoryList
.
As a result, $finalListToRemove
contains a list of full paths to the empty directories, making them ready for removal.
$finalListToRemove
Output of the $finalListToRemove
:
Now we have the folders list to be removed.
Delete Items From a Collection in PowerShell
It is possible to use the ForEach-Object
cmdlet to loop through the items in a collection. Inside the loop, we can use the Remove-Item
cmdlet.
$finalListToRemove | ForEach-Object { Remove-Item $_ }
The $_
denotes the current item in the collection. This will delete the testD
and testH
folders.
There is a tricky part here. When the testH
folder is deleted, the testG
directory becomes empty too.
Therefore, we need to modify the script a bit. We should run the above procedure until we are left with non-empty folders.
We can use the do...while
loop to do that.
$path = "D:\testA"
do {
$fetchedDirList = Get-ChildItem $path -Directory -Recurse
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName).count -eq 0 }
$finalListToRemove = $emptyDirectoryList | select -ExpandProperty FullName
$finalListToRemove | ForEach-Object { Remove-Item $_ }
} while ( $finalListToRemove.count -gt 0 )
In this block of code, we set up a loop to systematically detect and delete empty directories within the designated path and its subdirectories. Inside the loop, we first use the Get-ChildItem
cmdlet to fetch all directories recursively from the specified path.
Then, we filter out the empty directories using the Where-Object
cmdlet. After extracting the full paths of these empty directories, we proceed to remove them one by one using the Remove-Item
cmdlet within a ForEach-Object
loop.
This loop iterates as long as there are empty directories remaining for removal, ensuring a thorough cleanup of empty directories within the specified path and its subdirectories.
When you need to consider the hidden files and folders, we can pass the -Force
parameter to the Get-ChildItem
cmdlet, as shown in the following.
$emptyDirectoryList = $fetchedDirList | where { (gci $_.fullName -Force).count -eq 0 }
Output:
Conclusion
In PowerShell, efficiently identifying and removing empty folders is vital for maintaining an organized file system. Through the strategic utilization of cmdlets like Get-ChildItem
, Where-Object
, and Remove-Item
, users can streamline directory management tasks.
These cmdlets enable comprehensive cleanup of directories within specified paths, enhancing system efficiency and organization. By harnessing PowerShell’s scripting environment, users can automate directory management processes, saving time and effort while ensuring a clutter-free file system.
With PowerShell’s robust capabilities, directory management becomes a seamless aspect of system administration, empowering users to maintain optimal system performance.
Nimesha is a Full-stack Software Engineer for more than five years, he loves technology, as technology has the power to solve our many problems within just a minute. He have been contributing to various projects over the last 5+ years and working with almost all the so-called 03 tiers(DB, M-Tier, and Client). Recently, he has started working with DevOps technologies such as Azure administration, Kubernetes, Terraform automation, and Bash scripting as well.