Reputation: 3057
I made a powershell script which is following
$Now = Get-Date
$Days = "1"
$TargetFolder = "D:\DatabaseBackup"
$Extension = "*.bak"
$LastWrite = $Now.AddDays(-$Days)
$Files = Get-Childitem $TargetFolder -Include $Extension -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
foreach ($File in $Files)
{
if ($File -ne $NULL)
{
write-host "Deleting File $File" -ForegroundColor "DarkRed"
Remove-Item $File.FullName | out-null
}
else
{
Write-Host "No more files to delete!" -ForegroundColor "Green"
}
}
Now this is a simple script to remove files from a directory .
I have files in my directory with names like this
adventure_Test-20150131-191938.bak
adventure_Test-20150131-152010.bak
adventure_Test-20150205-191938.bak
adventure_Test-20150205-195038.bak
ontherDatabase-20150205-191938.bak
ontherDatabase-20150205-195038.bak
now you can see we have two files in 31th Jan 2015
and two files in 5th Feb 2015
. I want to delete all files except last two added and we have date time in file name to distinguished
Update I want to leave two newest files for each database backup
Upvotes: 0
Views: 3095
Reputation: 68273
Your timestamps are implicit in the filenames and in string-sortable format, so you don't really need to do any datetime manipulation to find the newest ones. Get the files grouped by database, then for each database sort the file names in descending order and they'll be in chronological order with the newest at the top.
$DBHash = @{}
$Retain = 2
$TargetFolder = "D:\DatabaseBackup"
$Extension = "*.bak"
Get-Childitem $TargetFolder -Include $Extension -Recurse |
Select Name,Fullname |
foreach { $DBHash[$_.Name.Split('-')[0]] += @($_) }
$DBHash.Values |
foreach {
$_ | sort -Descending |
Select -Skip $Retain |
foreach { Remove-Item $_.FullName }
}
Upvotes: 1
Reputation: 22831
You can use the following approach:
$bakfiles = Get-ChildItem *.bak
$flist = @()
foreach($backup in $bakfiles) {
if ( $backup.name -match '(\w+)\-(\d{8}\-\d{6})\.bak') {
$dt = [DateTime]::ParseExact($matches[2],"yyyyMMdd-HHmmss",$null)
$o = [PSCustomObject]@{path=$backup.FullName;backupDate=$dt;dbName=$matches[1]}
$flist += ,$o
}
}
$grouped = $flist | Sort-Object -Property BackupDate | Group-Object dbname
foreach($bgroup in $grouped) {
for($i = 0; $i -lt $bgroup.count-2; $i++) {
Remove-Item $bgroup.group[$i].path -WhatIf
}
}
Fist we iterate all the .bak
files in your directory.
On each of these we examine the filename to ensure it fits the format, and use a regular expression to extract the database name and date of backup. The [DateTime]::ParseExact
can be used to create date objects which it will be eaiser to compare. All these properties are stored in a PSCustomObject
and added to an array because we can then use standard cmdlets to filter, sort and group the list.
Once we have the array of objects, we can sort by the backup date, and group them together. We can then iterate the groups and remove all but the last 2 files, as these will be the last files for that database.
If you're happy with the script, you can remove the WhatIf
parameter on the Remove-Item
cmdlet and the files will be deleted instead of displaying what will be deleted.
Upvotes: 1