Powershell – Delete only files leaving empty sub-folders using powershell

powershellpowershell-v4.0

C:\Temp\ifc has about 297 folders inside it with roughly 4.1 million files spread amongst them.

Using a script I found elsewhere on this site, I wrote the following to delete all 'files' which are older than 1 hour.

$TargetFolder = “C:\Temp\ifc”
$NumberRange = "-1"
Get-ChildItem $TargetFolder -Recurse | Where {$_.lastwritetime -lt (Get-Date).AddHours($NumberRange)} | Remove-Item

The problem I am having is that it is deleting the sub-folders as well (if these folders end up with no files in them).

What can I add to this so that it leaves the folder structure in place?

Many Thanks.

Best Answer

You could add an additional where clause to ignore folders like this:

Where-Object{!($_.PSIsContainer)}

In the code snippet above;

  • ! means not,
  • $_ means current value of object in the pipe,
  • PSIsContainer is a property of the current object that returns true or false depending on if it is a folder or not.

So !($_.PSIsContainer) means current value of object in pipe is not a folder,
which is evaluated by Where-Object{}

Then your script would be like this:

$TargetFolder = “C:\Temp\ifc\”
$NumberRange = "-1"
Get-ChildItem $TargetFolder -Recurse | Where-Object{!($_.PSIsContainer)} | Where {$_.lastwritetime -lt (Get-Date).AddHours($NumberRange)} | Remove-Item

Another approach is to ignore the folders at the call to Get-ChildItem using the -File parameter like this:

$TargetFolder = “C:\Temp\ifc\”
$NumberRange = "-1"
Get-ChildItem $TargetFolder -File -Recurse | Where {$_.lastwritetime -lt (Get-Date).AddHours($NumberRange)} | Remove-Item

This approach has the benefit of returning the file objects at a sooner point in the execution cycle and making the command line shorter. Depending on the number of objects in the path, this may also have a measurable speed improvement.