How to delete empty subfolders with PowerShell?

39,705

Solution 1

I would do this in two passes - deleting the old files first and then the empty dirs:

Get-ChildItem -recurse | Where {!$_.PSIsContainer -and `
$_.LastWriteTime -lt (get-date).AddDays(-31)} | Remove-Item -whatif

Get-ChildItem -recurse | Where {$_.PSIsContainer -and `
@(Get-ChildItem -Lit $_.Fullname -r | Where {!$_.PSIsContainer}).Length -eq 0} |
Remove-Item -recurse -whatif

This type of operation demos the power of nested pipelines in PowerShell which the second set of commands demonstrates. It uses a nested pipeline to recursively determine if any directory has zero files under it.

Solution 2

In the spirit of the first answer, here is the shortest way to delete the empty directories:

ls -recurse | where {!@(ls -force $_.fullname)} | rm -whatif

The -force flag is needed for the cases when the directories have hidden folders, like .svn

Solution 3

This will sort subdirectories before parent directories working around the empty nested directory problem.

dir -Directory -Recurse |
    %{ $_.FullName} |
    sort -Descending |
    where { !@(ls -force $_) } |
    rm -WhatIf

Solution 4

Adding on to the last one:

while (Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Test-Path) {
    Get-ChildItem $StartingPoint -recurse | where {!@(Get-ChildItem -force $_.fullname)} | Remove-Item
}

This will make it complete where it will continue searching to remove any empty folders under the $StartingPoint

Solution 5

To remove files older than 30 days:

get-childitem -recurse |
    ? {$_.GetType() -match "FileInfo"} |
    ?{ $_.LastWriteTime -lt [datetime]::now.adddays(-30) }  |
    rm -whatif

(Just remove the -whatif to actually perform.)

Follow up with:

 get-childitem -recurse |
     ? {$_.GetType() -match "DirectoryInfo"} |
     ?{ $_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0 } |
     rm -whatif
Share:
39,705
Admin
Author by

Admin

Updated on June 18, 2020

Comments

  • Admin
    Admin almost 4 years

    I have a share that is a "junk drawer" for end-users. They are able to create folders and subfolders as they see fit. I need to implement a script to delete files created more than 31 days old.

    I have that started with Powershell. I need to follow up the file deletion script by deleting subfolders that are now empty. Because of the nesting of subfolders, I need to avoid deleting a subfolder that is empty of files, but has a subfolder below it that contains a file.

    For example:

    • FILE3a is 10 days old. FILE3 is 45 days old.
    • I want to clean up the structure removing files older than 30 days, and delete empty subfolders.
    C:\Junk\subfolder1a\subfolder2a\FILE3a
    
    C:\Junk\subfolder1a\subfolder2a\subfolder3a
    
    C:\Junk\subfolder1a\subfolder2B\FILE3b
    

    Desired result:

    • Delete: FILE3b, subfolder2B & subfolder3a.
    • Leave: subfolder1a, subfolder2a, and FILE3a.

    I can recursively clean up the files. How do I clean up the subfolders without deleting subfolder1a? (The "Junk" folder will always remain.)