Thursday, April 9, 2009

Powershell script to remove empty directories

Here's  a Powershell script that I've just created to remove empty folders which I'm sure I'm not going to need again in the future.

$items = Get-ChildItem -Recurse

foreach($item in $items)
{
      if( $item.PSIsContainer )
      {
            $subitems = Get-ChildItem -Recurse -Path $item.FullName
            if($subitems -eq $null)
            {
                  "Remove item: " + $item.FullName
                  Remove-Item $item.FullName
            }
            $subitems = $null
      }
}

 

 

17 comments:

  1. If you're sure you going to need the empty folders again in the future then why on earth are you removing them???

    ReplyDelete
  2. In this case I'd written a script which had accidentally created a ton of new empty folders deep inside and large folder tree and I didn't want to manual click through the tree to remove all of them.

    ReplyDelete
  3. Thanks for the script

    ReplyDelete
  4. Give this a whirl. It will not error on an empty folder. It will delete all files older than 30 days and leave folders alone.
    Take out Where {!$_.PSIsContainer} if you want to nuke every file and folder.
    Change to Where {$_.PSIsContainer}| to nuke every folder. (Does not check for files in subfolders...)
    ---scriptstart----
    $Now = Get-Date
    $Days = “30”
    $TargetFolder = “C:\Test”
    $LastWrite = $Now.AddDays(-$days)
    $Files = get-childitem $TargetFolder -recurse -force | Where {!$_.PSIsContainer}|Where {$_.LastWriteTime -le “$LastWrite”}
    foreach ($File in $Files)
    {IF ($Files -ne $NULL)
    {write-host “Deleting File $File.FullName” -foregroundcolor “Red” ; Remove-Item $File.FullName -recurse -force
    }
    }
    ---script end----

    ReplyDelete
  5. Thanks jwagner - appreciated.

    ReplyDelete
  6. With some of the ideas posted here i created the following script to cleanup my music folders. I had to many empty folders where the music got pulled out and re-organized by iTunes.
    ---------------------------------------
    Param ([system.io.directoryinfo]$folderpath = $(throw "provide folderpath"))
    $folders = get-childitem $folderpath -recurse -force | ? {$_.PSIsContainer}
    if ($folders -ne $null)
    {
    [array]::Reverse($folders)
    foreach($folder in $folders)
    {
    write-host "-----------------------------------------"
    write-host "Examining contents of $($folder.fullname)"
    $childitems = Get-Childitem $folder.fullname -recurse -force | ? {($_.fullname -like "*.mp3") -or ($_.fullname -like "*.m4a") -or ($_.fullname -like "*.wma")`
    -or ($_.fullname -like "*.aa") -or ($_.fullname -like "*.aax")}
    if($childitems -eq $null)
    {
    "Remove folder: " + $folder.FullName
    Remove-Item $folder.FullName -recurse -force
    }
    else
    {
    write-host "media found in $folder, skipping delete"
    }
    write-host "-----------------------------------------"
    $childitems = $null
    }
    }
    else
    {
    write-host "no sub folders found"
    }

    ReplyDelete
  7. Hi - loved it (although I'm too gutless to run it in case some empty folders simply "have to be there" for an application to run correctly).
    What I'm wondering is - is it possible to re-design this script so that it will recurse through the C drive and provide a list of sets of folders with identical contents; all the "Duplicate Finders" are too granular insofar as they work on the duplicate file level, whereas I only want to identify pairs (or triples, or quads...) of (possibly distinctly named) folders with the exact same file and folder sub-structure.
    Also as a real challenge, replace the notion "folders with the exact same file and folder sub-structure" with "folders, one of which is a proper subset of the other".
    I know this is asking a lot, but at the same time it might be quite a challenge, mightn't it? I won't consider it cheating if the script simply generates (say) csv data to be further examined using Excel or SQLServer!!!
    Scott

    ReplyDelete
  8. the first script above .. how would you use that against another path .. how would i change this so it will run against a drive letter or a unc path ..
    $items = Get-ChildItem -Recurse
    foreach($item in $items)
    {
    if( $item.PSIsContainer )
    {
    $subitems = Get-ChildItem -Recurse -Path $item.FullName
    if($subitems -eq $null)
    {
    "Remove item: " + $item.FullName
    Remove-Item $item.FullName
    }
    $subitems = $null
    }
    }
    i tried to run it and it just keeps using the local drive i cannot get it to run in another script with the path of the server volume - either using the unc naming or thr drive letter on the system that is running it .
    thanks in advance

    ReplyDelete
  9. Thanks for posting-saves time.

    ReplyDelete
  10. I had accidentally run a Duplicate file delete program and forgot to check "Delete Empty Folders". This PS script cleared out all these empty folders in a snap. Thanks!!

    ReplyDelete
  11. i want a script which delete folder that contain only one file in it.
    i.e. i have one folder named abc . this folder contain 5000 sub folder & each sub folder contain files thay may be from 1 to 15 . i just want to delete sub folders that contain only one file in it. all the others folder should remain intact.
    Thanks in advance.

    ReplyDelete
  12. Compressed version of the script above:
    $folder=<root folder from which you want to clear out empty folders>
    ls $folder|%{if($_.psIsContainer -and !(ls $_.fullName)){echo "Removing $($_.fullName)"; del $_.fullName -force -recurse}}
    And for Amit:
    ls $folder|%{if($_.psIsContainer -and (@(ls $_.fullName).count -eq 1)){echo "Removing $($_.fullName)"; del $_.fullName -force -recurse}}
    Cheers!!

    ReplyDelete
  13. One Problem with this Script:
    If it deletes an empty folder and the result is that the folder above it is now empty then this script doesn't delete the new empty folder. To fix this the foreach loop should be a for loop starting from the end of the $items array and moving to the front:
    for($i=$items.length-1 ;$i -ge 0; $i--)
    {
    $item = $items[$i]
    ....

    ReplyDelete
  14. That's a great idea taapes - thanks!

    ReplyDelete
  15. Great post paired with very useful scripts in the comments as well! Thanks all...your scripts/tips helped me setup a purge routine in a matter of mins :)

    ReplyDelete
  16. Good job guys.
    I have a problem that I'm trying to fix using powershell.
    I used a software (AllDup) to remove duplicate files from different folders, but I made a mistake and deleted the files in the wrong folder (the good one) and kept the files in the wrong folder.
    Then I need to make a script to check for empty folders from one location and replace it with the other folders.
    So I need to do is:
    1 -. Check the folders with the same name in location A and B and get the empy ones in B
    2 -. Using these results I need to move the duplicate folders from B to A
    Such that if a folder exists at location A ("A:\folder\fine") move it to the folder that corresponds in B ("B:\folder\folder\folder\fine")
    Can anyone help me with this?
    Thanks in advance!

    ReplyDelete
  17. Hmm i dont understand how to fill the "taapes" part into place, need to delete files older than 30d im doing it this way:
    $DateToDelete = 30
    $StartFolder = "c:\asd\"
    dir $StartFolder -Recurse -Force -ea 0 | ?{!$_.PsIsContainer -and $_.LastWriteTime -lt (Get-Date).AddDays(-$DateToDelete)} | del -Force
    ----------
    afterwards need to delete empty folders with empty subfolders, problem is it only delete 1 empty folder at the time so i need to rerun it multiple time, any idea what to fix in there?:
    Get-ChildItem $StartFolder -recurse | `
    ? {$_.GetType() -match "DirectoryInfo"} | `
    ?{ $_.GetFiles().Count -eq 0 -and $_.GetDirectories().Count -eq 0 } | `
    rm -force

    ReplyDelete