Clean up files and folders older than x days

I want to clean up the files and folders of a FTP server which is used by my customers and want to use 3 steps:

  1. Remove files with a specific file extension or name older than x days
  2. Remove all files older than x days in specific folders
  3. Remove empty folders except when the folders has a specific name
    This is the script I created:

Step 1 and 2 are working, but step 3 is not deleting any folders.
I hope somebody can help me to fix this problem.

$now = Get-Date    
$days = "10"     
$lastwrite = $now.AddDays(-$days)     
$folders = Get-ChildItem -Path $Path –Recurse -force    
$path = "C:\test\"      
$include = "*.xml", "*.done_ppr", "*.done_pps", "*.pps", "*.ppr", "*.pf_done", "*order_sprint*.*" 
$skipList = "incoming", "outgoing", "test"      
$includeFolderList = "C:\test\test", "C:\test\test2" 


# Remove files older than the $limit - All-folders only included extensions.
Get-ChildItem -Path $path -Recurse -Force -include $include | 
Where-Object { !$_.PSIsContainer -and $_.LastWriteTime -lt $lastwrite } | 
Remove-Item -Force 

# Remove files older than the $limit - Folder in $includefolderlist and all extensions
Get-ChildItem -Path $includeFolderList -Recurse -Force  |
Where-Object { !$_.PSIsContainer -and $_.LastWriteTime -lt $lastwrite } | 
Remove-Item -Force 


# Remove any empty foldes - All folder with exeption of folders in $skiplist
foreach ($folder in $folders)
{
  if ($skipList -contains $folder) 
  {
    Write-Host "'$folder' is in array"
  }
  else
  {
    Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse      -Force | 
    Where-Object { !$_.PSIsContainer }) -eq 0} | 
    Remove-Item -Force -Recurse 
  } 

Gerard,
Welcome to the forum. :wave:t4:

So maybe some tips are enough … :wink:

In general: Get-ChildItem has the parameters -File and -Directory. With these you can limit the output to either files or folders and you do not have to filter them later on with a Where-Object.

Inside your loop you use an if condition and the -contains operator. This operator checks if an element is in a list. But this element has to be exactly the same in the list. So it will not work if you check a complete folder path and you only have parts of the folder path in your list. :wink:

Hi Olaf,

Thank you for the tips! But I’m afraid I need some more…

I changed the $ folder, so it will limit the output to only the directory’s

$folders = Get-ChildItem -Directory $Path –Recurse -force 

and when I run the loop, I get the following output.

'Incoming' is in array
'Outgoing' is in array
'test' is in array
'incoming' is in array
'outgoing' is in array
'TEST' is in array
'TEST' is in array
'Incoming' is in array
'Outgoing' is in array 

So the “if” part of my loop seems to be working, but the “else” part is not.

I cannot reproduce the behaviour you show.

Since you said the first 2 steps work for you we only focus on the last one. I’d recommend to exclude the desired folders already when querying the list. … like this:

$path = 'C:\test\'
$skipList = 'incoming', 'outgoing', 'test'      

$folderList = Get-ChildItem -Path $Path -Exclude $skipList –Recurse -Force -Directory

foreach ($folder in $folderList) {
    if (-not (Get-ChildItem -Path $folder.FullName)) {
        Remove-Item -Path $folder.FullName -WhatIf
    }
}

When you successfully tested it you can remove the -WhatIf

1 Like

nice, I didn’t know you could exclude folders like that. I was using nested if statement /o\. I’ve learned a lot lurking here for the past month :slight_smile:

wanted to check, to remove empty folders can we use not like below?

foreach ($folder in $folderList) {
    if (-not (Get-ChildItem -Path $folder.FullName)) {
        Remove-Item -Path $folder.FullName -WhatIf
    }
}

@mawazo you’re right, good catch - my mistake. :wink: :+1:t4: I changed my answer to not confuse future readers.

Thanks.

Hello Olaf and Mazowa,

This the solution for my problem, thanks!!