Search code examples
powershelldirectoryget-childitem

Powershell Find all empty folders and subfolders in a given Folder name


I´m trying to get a a) list of all empty folders and subfolders if the folder is named "Archiv" b) I´d like to delete all those empty folders. My current approch doesn´t check the subfolders.

It would be also great if the results would be exportet in a .csv =)

$TopDir = 'C:\Users\User\Test'

$DirToFind = 'Archiv'>$EmptyDirList = @(
    Get-ChildItem -LiteralPath $TopDir -Directory -Recurse |
        Where-Object {
            #[System.IO.Directory]::GetFileSystemEntries($_.FullName).Count -eq 0
            $_.GetFileSystemInfos().Count -eq 0 -and
            $_.Name -match $DirToFind
            }
        ).FullName

$EmptyDirList

Any ideas how to adjust the code? Thanks in advance


Solution

  • You need to reverse the order in which Get-ChildItem lists the items so you can remove using the deepest nested empty folder first.

    $LogFile = 'C:\Users\User\RemovedEmptyFolders.log'
    $TopDir  = 'C:\Users\User\Test'
    
    # first get a list of all folders below the $TopDir directory that are named 'Archiv' (FullNames only)
    $archiveDirs = (Get-ChildItem -LiteralPath $TopDir -Filter 'Archiv' -Recurse -Directory -Force).FullName | 
                    # sort on the FullName.Length property in Descending order to get 'deepest-nesting-first' 
                    Sort-Object -Property Length -Descending 
    
    # next, remove all empty subfolders in each of the $archiveDirs
    $removed = foreach ($dir in $archiveDirs) {
        (Get-ChildItem -LiteralPath $dir -Directory -Force) |
        # sort on the FullName.Length property in Descending order to get 'deepest-nesting-first' 
        Sort-Object @{Expression = {$_.FullName.Length}} -Descending | 
        ForEach-Object {
           # if this folder is empty, remove it and output its FullName for the log
           if (@($_.GetFileSystemInfos()).Count -eq 0) { 
               $_.FullName
               Remove-Item -LiteralPath $_.FullName -Force
           }
        }
        # next remove the 'Archiv' folder that is now possibly empty too
        if (@(Get-ChildItem -LiteralPath $dir -Force).Count -eq 0) {
            # output this folders fullname and delete
            $dir
            Remove-Item -LiteralPath $dir -Force
        }
    }
    
    $removed | Set-Content -Path $LogFile -PassThru  # write your log file. -PassThru also writes the output on screen