Deleting files in subfolders older than x days - powershell

I am trying to delete all files in subfolders of a given folder without deleting the subfolders themselves. I have tried various examples but they are not doing what I expect.
The basic structure of the file tree I am trying to negotiate is:
C:\Backups\Subfolder1
C:\Backups\Subfolder2
C:\Backups\Subfolder3
and I am using the following code:
$limit = (Get-Date).AddDays(-14)
$path = "C:\Backups"
Get-ChildItem -Path $path -Recurse -Force |
Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } |
Remove-Item -WhatIf
I am finding that the files in the subdirectories are being ignored despite the -Recurse flag being used, although any files in the C:\Backups directory are included. If I remove the !$_.PSIsContainer clause the file in the subfolder is included but so are all of the directories.
Can anyone show me how to include the files in the subfolder while still ignoring the subfolders themselves?

If you are using powershell 3.0 you can simply use the -File switch:
$limit = (Get-Date).AddDays(-14)
$path = "C:\Backups"
Get-ChildItem -Path $path -File -Recurse | where { $_.LastWriteTime -lt $limit } | Remove-Item

The below code works for me. Are you on an older version of powershell?
$limit = (Get-Date).AddDays(-14)
$path = "C:\Users\nathan.cooper\Documents"
Get-ChildItem -Path $path -Recurse -Force |
where { (! $_.PSIsContainer) -and ($_.LastWriteTime -lt $limit) } |
Remove-Item -whatif

$limit = (Get-Date).AddDays(-14)
$files = Get-ChildItem -Path C:\Backups -Directory:$false -Recurse
$files | ForEach-Object -Process {
if($_.CreationTime -lt $limit)
{
Remove-Item $_.FullName -Force
}
}
The -Directory:$False parameter means you don't have to worry about deleting any directories because they won't be included in the array.

Related

Delete old files after X days by default with exception on certain dirs [Powershell]

I'm trying to fix the following scenario:
I have directory which has multiple subdirectories and files where I need to set something like retention policy, by default I would set to have files no older than 365 days where there are some special directories where I would like to keep for a different period of time other than my default value. These directories are specified in a txt file with the following syntax
Content of Drive:\Path\to\special_dirs.txt
D:\Path\to\vendor1 -396
D:\Path\to\vendor2 -45
This is what I have come up so far (It is working on the special directories only, the next part where I want to proceed with the rest does not work):
# Script to remove old files from Archive: D:\Path\to
# Declaring variables to be used
$controlfile = "Drive:\Path\to\list\special_dirs.txt"
$dir = "D:\Path\to"
$default_days = "-365"
$excluded_dirs = Get-Content $controlfile | Foreach-Object {$_.Split()[0]}
foreach ($line in Get-Content $controlfile) {
$split = $line.split(" ")
$file_path = $split[0]
$max_days = $split[1]
Get-ChildItem $file_path -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays($max_days))} | Remove-Item -Force -Recurse -Verbose -WhatIf
}
# Removing everything else older than 365 days old
Get-ChildItem -Path $dir -Include *.* -File -Recurse -Directory -Exclude $excluded_dirs | Where-Object {($_.LastWriteTime -lt $curr_date.AddDays($default_days))} | Remove-Item -Force -Recurse -Verbose -WhatIf
I'm not looking to remove directories even if they are empty, I just want to remove files, the last part of the script just deletes everything older than 365 day where there is a directory that I would like to keep 30 days more than the default period of time, any ideas on how to get this done?
I used the file list so that I can keep adding directories to vendors where I can keep longer than or even less than the default days.
What about something like this?..
$30DayDirs = #('C:\Temp\Test1\','C:\Temp\Test2\')
$60DayDirs = #('C:\Temp\Test3\')
$365DayDirs = #('C:\Temp\Test4\')
foreach($file in $30DayDirs){
$file = Get-ChildItem $30DayDirs -Recurse |where LastWriteTime -LT (Get-Date).AddDays(-30)
Remove-Item $file.FullName -Force -Recurse
}
foreach($file in $60DayDirs){
$file = Get-ChildItem $60DayDirs -Recurse |where LastWriteTime -LT (Get-Date).AddDays(-60)
Remove-Item $file.FullName -Force -Recurse
}
foreach($file in $365DayDirs){
$file = Get-ChildItem $365DayDirs -Recurse |where LastWriteTime -LT (Get-Date).AddDays(-365)
Remove-Item $file.FullName -Force -Recurse
}
I have fixed my issue with the following:
# Script to remove old files from DFS Archive: D:\Path\to
# Declaring variables to be used
$controlfile = "Drive:\Path\to\list\special_dirs.txt"
$dir = "D:\Path\to"
$default_days = "-365"
$excluded_dirs = Get-Content $controlfile | Foreach-Object {$_.Split()[0]}
# Removing old files from special directories first
cd $dir
foreach ($line in Get-Content $controlfile) {
$split = $line.split(" ")
$file_path = $split[0]
$max_days = $split[1]
Get-ChildItem $file_path -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays($max_days))} | Remove-Item -Force -Recurse -Verbose
}
# Removing everything else older than 365 days old
Get-ChildItem $dir -Directory -Exclude $excluded_dirs | Get-ChildItem -Include *.* -File -Recurse | Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays($default_days))} | Remove-Item -Force -Recurse -Verbose
And I have modified my special_dirs.txt file to:
vendor1 -396
vendor2 -45

Keep first layer of folders from Get-ChildItem when moving

I am working on some PowerShell script that automatically moves folders and files from the 'X-Drive' folder and move it into the 'Old' folder which also is inside the 'X-Drive' folder, but I want it to keep the first layer folders only, all what's inside can be moved but only the folder needs to be kept, but it also needs to be in the 'Old' folder.
$exclude = #('Keep 1', 'Keep 2')
Get-ChildItem -Path "C:\X-Drive" -Recurse -Exclude $exclude |
Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-0) } |
Move-Item -Destination "C:\X-Drive\Old" -ErrorAction 'SilentlyContinue'
Enumerate the subfolders of C:\X-D_rive, then move their content to corresponding subfolders in C:\X-Drive\old, e.g. like this:
$refdate = (Get-Date).AddDays(-1)
Get-ChildItem 'C:\X-Drive' -Directory -Exclude $exclude | ForEach-Object {
$dst = Join-Path 'C:\X-Drive\old' $_.Name
If (-not (Test-Path -LiteralPath $dst)) {
New-Item -Type Directory -Path $dst | Out-Null
}
Get-ChildItem $_.FullName -Recurse | Where-Object {
$_.LastWriteTime -lt $refdate
} | Move-Item -Destination $dst
}
You may want to add old to $excludes, BTW.
The code assumes you're running PowerShell v3 or newer.

Powershell Cleanup script. Excluded folder not being excluded

I wrote a simple script that will run as a scheduled task every weekend. This script cleans up files older than # days and you can give the name of a folder for exclusion as a parameter. This folder should not be cleaned up by the script. But somehow the script still deletes some files from the excluded folder. But in a strange way no files matching the conditions of the parameter.
For example I run the script to delete files older than 15 days and exclude the folder NOCLEANUP. but some files still get deleted from that folder, but there are still files older than 15 days in the NOCLEANUP folder.
Code below
Thanks in advance and apologies for the dirty code. Still new to PS.
Function CleanDir ($dir, $days, $exclude, $logpath)
{
$Limit = (Get-Date).AddDays(-$days)
$Path = $dir
#Folder to exclude
$ToExclude = $exclude
#Log location
$Log= $logpath
$Testpath = Test-Path -PathType Container -Path $Log
if ($Testpath -ne $true)
{
New-Item -ItemType Directory -Force -Path $Log
}
#Logs deleted files
cd $Log
Get-ChildItem -Path $Path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastwriteTime -lt $Limit } | Where-Object { $_.fullname -notmatch $ToExclude} | Where-Object { $_.fullname -notmatch '$RECYCLE.BIN'} | Out-File -FilePath CLEANUPLOG.TXT
# Delete files older than the $Limit.
Get-ChildItem -Path $Path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.LastwriteTime -lt $Limit } | Where-Object { $_.fullname -notlike $ToExclude} | Remove-Item -Force -Recurse
#Goes into every folder separately and deletes all empty subdirectorys without deleting the root folders.
$Folder = Get-ChildItem -Path $Path -Directory
$Folder.fullname | ForEach-Object
{
Get-ChildItem -Path $_ -Recurse -Force | Where-Object {$_.PSIsContainer -eq $True} | Where-Object {$_.GetFiles().Count -eq 0} | Remove-Item -Force -Recurse
}
}

Delete Folders recently moved to a different directory after 10 days of moving

There is a directory where I am moving folders, from a different directory without any logic(randomly anytime) and these folders needs to be deleted after 10 days of their moving here.
So, will this work? -
$limit = (Get-Date).AddDays(-10)
$path = "C:\Some\Path"
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
What I don't know is that this creation time parameter would be updated when I move it to the new directory???
As requested in comments, a solution with renaming folders:
Moving a folder:
$sOldPath = "C:\oldpath\foldertomove" # Change to your actual path
$sNewPath = "C:\newpath" # Change to your actual new path
$sDate = Get-Date -Format "yyyMMdd"
$oFolderToMove = Get-Item -Path $sOldPath
Move-Item -Path $sOldPath -Destination $sNewPath
Rename-Item -Path (Join-Path -Path $sNewPath -ChildPath $oFolderToMove.Name) `
-NewName ("{0}-{1}" -f $sDate, $oFolderToMove.Name)
Resulting path: C:\newpath\yyyyMMdd-foldertomove
Deleting old folders:
$sNewPath = "C:\newpath" # Change to your actual new path
$sDateLimit = ((Get-Date).AddDays(-10)).ToString("yyyyMMdd")
# Assuming that all folders in $sNewPath have date-prefixed names.
Get-ChildItem -Path $sNewPath |
Where-Object { $_.PSIsContainer } |
Foreach-Object {
$sDate = [UInt32]($_.Name.Substring(0,8))
if ($sDate -lt $sDateLimit) {
# Deletes folder and everything in it. Remove -WhatIf switch to execute.
Remove-Item -Path $_.FullName -Recurse -Force -WhatIf
}
}

Delete files older than 15 days using PowerShell

I would like to delete only the files that were created more than 15 days ago in a particular folder. How could I do this using PowerShell?
The given answers will only delete files (which admittedly is what is in the title of this post), but here's some code that will first delete all of the files older than 15 days, and then recursively delete any empty directories that may have been left behind. My code also uses the -Force option to delete hidden and read-only files as well. Also, I chose to not use aliases as the OP is new to PowerShell and may not understand what gci, ?, %, etc. are.
$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"
# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
# Delete any empty directories left behind after deleting the old files.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object { !$_.PSIsContainer }) -eq $null } | Remove-Item -Force -Recurse
And of course if you want to see what files/folders will be deleted before actually deleting them, you can just add the -WhatIf switch to the Remove-Item cmdlet call at the end of both lines.
If you only want to delete files that haven't been updated in 15 days, vs. created 15 days ago, then you can use $_.LastWriteTime instead of $_.CreationTime.
The code shown here is PowerShell v2.0 compatible, but I also show this code and the faster PowerShell v3.0 code as handy reusable functions on my blog.
just simply (PowerShell V5)
Get-ChildItem "C:\temp" -Recurse -File | Where CreationTime -lt (Get-Date).AddDays(-15) | Remove-Item -Force
Another way is to subtract 15 days from the current date and compare CreationTime against that value:
$root = 'C:\root\folder'
$limit = (Get-Date).AddDays(-15)
Get-ChildItem $root -Recurse | ? {
-not $_.PSIsContainer -and $_.CreationTime -lt $limit
} | Remove-Item
Basically, you iterate over files under the given path, subtract the CreationTime of each file found from the current time, and compare against the Days property of the result. The -WhatIf switch will tell you what will happen without actually deleting the files (which files will be deleted), remove the switch to actually delete the files:
$old = 15
$now = Get-Date
Get-ChildItem $path -Recurse |
Where-Object {-not $_.PSIsContainer -and $now.Subtract($_.CreationTime).Days -gt $old } |
Remove-Item -WhatIf
Try this:
dir C:\PURGE -recurse |
where { ((get-date)-$_.creationTime).days -gt 15 } |
remove-item -force
Esperento57's script doesn't work in older PowerShell versions. This example does:
Get-ChildItem -Path "C:\temp" -Recurse -force -ErrorAction SilentlyContinue | where {($_.LastwriteTime -lt (Get-Date).AddDays(-15) ) -and (! $_.PSIsContainer)} | select name| Remove-Item -Verbose -Force -Recurse -ErrorAction SilentlyContinue
If you are having problems with the above examples on a Windows 10 box, try replacing .CreationTime with .LastwriteTime. This worked for me.
dir C:\locationOfFiles -ErrorAction SilentlyContinue | Where { ((Get-Date)-$_.LastWriteTime).days -gt 15 } | Remove-Item -Force
Another alternative (15. gets typed to [timespan] automatically):
ls -file | where { (get-date) - $_.creationtime -gt 15. } | Remove-Item -Verbose
#----- Define parameters -----#
#----- Get current date ----#
$Now = Get-Date
$Days = "15" #----- define amount of days ----#
$Targetfolder = "C:\Logs" #----- define folder where files are located ----#
$Extension = "*.log" #----- define extension ----#
$Lastwrite = $Now.AddDays(-$Days)
#----- Get files based on lastwrite filter and specified folder ---#
$Files = Get-Childitem $Targetfolder -include $Extension -Recurse | where {$_.LastwriteTime -le "$Lastwrite"}
foreach ($File in $Files)
{
if ($File -ne $Null)
{
write-host "Deleting File $File" backgroundcolor "DarkRed"
Remove-item $File.Fullname | out-null
}
else {
write-host "No more files to delete" -forgroundcolor "Green"
}
}
$limit = (Get-Date).AddDays(-15)
$path = "C:\Some\Path"
# Delete files older than the $limit.
Get-ChildItem -Path $path -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force -Recurse
This will delete old folders and it content.
The following code will delete files older than 15 days in a folder.
$Path = 'C:\Temp'
$Daysback = "-15"
$CurrentDate = Get-Date
$DatetoDelete = $CurrentDate.AddDays($Daysback)
Get-ChildItem $Path -Recurse | Where-Object { $_.LastWriteTime -lt $DatetoDelete } | Remove-Item