【问题标题】:Backupfile deleter备份文件删除器
【发布时间】:2021-08-18 19:00:10
【问题描述】:

我有一个充满备份文件的目录,但需要自动清理该目录,因为空间不足。最简单的方法是使用 powershell 脚本。

备份每天创建 2 个备份。我想每天保留 2 个备份 7 天,超过 7 天但不超过 3 个月的备份我想每天保留 1 个,超过 3 个月的所有备份我想每周保留 1 个。超过 2 年的所有内容都会被删除。

我写的第一个函数会删除超过 2 年的所有内容:

$checkPath = "C:\demo\"
$list = (Get-ChildItem -Path $checkPath | Where-Object {$_.LastWriteTime -lt (Get-Date).AddYears(-2)}).FullName
$count = $list.Length
for ($i = 0; $i -lt $count; $i += 1)
{
    Write-Verbose "[$i] $($list[$i])"
    Remove-Item -Path $list[$i] 
}

之后我创建了一个函数来删除每个第二次备份:

$checkPath = "C:\demo\"
$list = (Get-ChildItem -Path $checkPath | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-7)} | Where-Object {$_.LastWriteTime -lt (Get-Date).AddMonths(-3)}).FullName
$count = $list.Length
for ($i = 0; $i -lt $count; $i += 2)
{
    Write-Verbose "[$i] $($list[$i])"
    Remove-Item -Path $list[$i] 
}

嗯,我觉得有点失落,我是在正确的道路上吗?有没有人可以建议“做得更好”?

【问题讨论】:

  • 您能简化您的备份删除请求吗?大声笑关于日期是
  • @AbrahamZinala 我希望我可以。在这种情况下,我只能使用 CreationTime 或 LastWriteTime。在 7 天内,我需要在接下来的 3 个月内每天 1 次保留 14 次备份,之后每周 1 次在 2 年内保留一次。
  • 备份是 same-ish 名称,都在同一个目录中吗?

标签: powershell file backup


【解决方案1】:

相同,除了代码中的内容之外,不会做太多细节。希望 cmets 说话声音够大

$checkPath = 'C:\temp'

$classified = switch ((Get-ChildItem -Path $checkPath -File | Group-Object { $_.LastWriteTime.Date }) ) {
    # Last 7 days
    { [datetime]::Parse(($_.Name)) -ge [datetime]::Today.AddDays(-7) } {
        $keep = $_.group | Sort-Object LastWriteTime | Select-Object -Last 2
        $keep | ForEach-Object {
            [pscustomobject]@{Path = $_.fullname; LastWriteTime = $_.LastWriteTime; Action = 'Keep'; Interval = '<= 7 days' }
        }
        $remove = $_.group | Where-Object { $_ -notin $keep }
        $remove | ForEach-Object {
            [pscustomobject]@{Path = $_.fullname; LastWriteTime = $_.LastWriteTime; Action = 'Remove'; Interval = '<= 7 days' }
        }
    }
    { [datetime]::Parse(($_.Name)) -lt [datetime]::Today.AddDays(-7) -and
        [datetime]::Parse(($_.Name)) -ge [datetime]::Today.AddMonths(-3) } {
        # Between 7 days and 3 months $_.Name -ForegroundColor Green

        $keep = $_.group | Sort-Object LastWriteTime | Select-Object -Last 1
        $keep | ForEach-Object {
            [pscustomobject]@{Path = $_.fullname; LastWriteTime = $_.LastWriteTime; Action = 'Keep'; Interval = 'Between 7 days and 3 months' }
        }
        $remove = $_.group | Where-Object { $_ -notin $keep }
        $remove | ForEach-Object {
            [pscustomobject]@{Path = $_.fullname; LastWriteTime = $_.LastWriteTime; Action = 'Remove'; Interval = 'Between 7 days and 3 months' }
        }
    }
    { [datetime]::Parse(($_.Name)) -lt [datetime]::Today.AddMonths(-3) -and
        [datetime]::Parse(($_.Name)) -ge [datetime]::Today.AddYears(-2) } {
        # Between 3 months and 2 years $_.Name -ForegroundColor Green
        # Set to unknown for now.  Group by weekOfYear later to make determination
        $_.group | ForEach-Object {
            [pscustomobject]@{Path = $_.Fullname; LastWriteTime = $_.LastWriteTime; Action = 'Unknown'; Interval = 'Between 3 months and 2 years' }
        }
    }
    Default {
        $_.group | ForEach-Object {
            # Everything after 2 years $_.Name -ForegroundColor Green
            [pscustomobject]@{Path = $_.fullname; LastWriteTime = $_.LastWriteTime; Action = 'Remove'; Interval = '> 2 years' }
        }
    }
}

# Needed to determine and group by week of year
$cultureInfo = [cultureinfo]::new('en-US')
$calendar = $cultureInfo.Calendar;
$calendarRule = $cultureInfo.DateTimeFormat.CalendarWeekRule
$firstDayOfWeek = $cultureInfo.DateTimeFormat.FirstDayOfWeek


$classified | Where-Object Interval -EQ 'Between 3 months and 2 years' |
    # Group all files between 3 months and 2 years by weekOfYear and Year and set latest one to keep, others to remove
    Group-Object { $calendar.GetWeekOfYear($_.LastWriteTime, $calendarRule, $firstDayOfWeek) }, { $_.LastWriteTime.Year } |
    ForEach-Object {
        $keep = $_.group | Sort-Object LastWriteTime | Select-Object -Last 1
        $keep | ForEach-Object { $_.Action = 'Keep' }

        $remove = $_.group | Where-Object { $_ -notin $keep }
        $remove | ForEach-Object { $_.Action = 'Remove' }
    }

$classified | Sort-Object LastWriteTime | Out-Host

$classified | Where-Object Action -EQ 'Remove' | Remove-Item -WhatIf

输出

Path                                                      LastWriteTime       Action Interval
----                                                      -------------       ------ --------
C:\temp\20210101 - 20210108.pdf                           13.01.2021 09:15:22 Keep   Between 3 months and 2 years
C:\temp\20210115 - 20210122.pdf                           26.01.2021 15:57:47 Keep   Between 3 months and 2 years
C:\temp\rm_50117.pbl                                      14.05.2021 15:26:41 Keep   Between 7 days and 3 months
C:\temp\zipped.zip                                        19.05.2021 18:35:12 Remove Between 7 days and 3 months
C:\temp\zipped2.zip                                       19.05.2021 18:40:54 Remove Between 7 days and 3 months
C:\temp\zipped3.zip                                       19.05.2021 18:46:05 Keep   Between 7 days and 3 months
C:\temp\xxx_Some Doc ID 2333 _other stuff_more stuff.junk 20.05.2021 23:32:43 Keep   Between 7 days and 3 months
C:\temp\testlksj.ps1                                      21.05.2021 22:28:03 Keep   Between 7 days and 3 months
C:\temp\skdljfsdkf.ps1                                    22.05.2021 09:04:29 Remove Between 7 days and 3 months
C:\temp\testparam.ps1                                     22.05.2021 17:08:33 Remove Between 7 days and 3 months
C:\temp\gitignorepath.txt                                 22.05.2021 21:03:06 Keep   Between 7 days and 3 months
C:\temp\lslkdfjl.ps1                                      23.05.2021 00:56:13 Remove Between 7 days and 3 months
C:\temp\test2.txt                                         23.05.2021 10:17:24 Remove Between 7 days and 3 months
C:\temp\test3.txt                                         23.05.2021 10:17:38 Remove Between 7 days and 3 months
C:\temp\test4.txt                                         23.05.2021 10:17:50 Keep   Between 7 days and 3 months
C:\temp\fromVS.txt                                        24.05.2021 22:57:44 Keep   <= 7 days
C:\temp\testlksfsdfsdj.ps1                                25.05.2021 16:55:45 Keep   <= 7 days
C:\temp\dslkfjlds.ps1                                     26.05.2021 23:35:23 Keep   <= 7 days
C:\temp\slkfjdslfj.ps1                                    27.05.2021 00:35:09 Keep   <= 7 days
C:\temp\testgit.log                                       31.05.2021 13:28:19 Keep   <= 7 days
C:\temp\out.log                                           31.05.2021 13:51:37 Keep   <= 7 days

What if: Performing the operation "Remove File" on target "C:\temp\zipped.zip".
What if: Performing the operation "Remove File" on target "C:\temp\zipped2.zip".
What if: Performing the operation "Remove File" on target "C:\temp\skdljfsdkf.ps1".
What if: Performing the operation "Remove File" on target "C:\temp\testparam.ps1".
What if: Performing the operation "Remove File" on target "C:\temp\lslkdfjl.ps1".
What if: Performing the operation "Remove File" on target "C:\temp\test2.txt".
What if: Performing the operation "Remove File" on target "C:\temp\test3.txt".

【讨论】:

  • 是的,我们有一个类似的想法,我只是更喜欢避免使用管道并采用更经典的方法。我想知道为什么我的代码看起来都是绿色的,想知道语法突出显示发生了什么?
  • @SantiagoSquarzon,我对您的答案进行了编辑,试图修复突出显示。看起来有效,只是需要得到某人的批准
  • 哦,哇,它固定了,我想知道为什么。始终使用三重反引号,从来没有任何问题。谢谢!您也可以按年份分组,或者您可以将多年的文件分组在一起感谢您的反馈,我现在正在修复代码。跨度>
【解决方案2】:

这里我就不多说了,只复习一下代码,阅读一下cmets。

需要考虑的一点是,在 Get-ChildItem "C:\demo\" -File 上,您可能需要考虑使用 -Filter 来仅过滤带有备份扩展名的文件。

请注意,我在 Remove-Item 上使用了 -WhatIf 标志,请查看脚本,如果您认为它正在执行您想要的操作,请删除此标志。

# Group all backups per day
# DateTime Format MM/dd/yyyy 12:00:00 AM
$backups = Get-ChildItem 'C:\demo\' -File |
           Group-Object {$_.CreationTime.Date} |
           Sort-Object -Descending {$_.Name -as [datetime]}
    
$date = [datetime]::Now
    
$onePerWeekGroups = foreach($group in $backups)
{
    switch($group)
    {
        {[datetime]$_.Name -ge $date.AddDays(-7)}
        {
            # Groups which Date is greater than or equal to
            # Date 7 Days ago
                
            # For this group (day), skip the first 2 backups and
            # remove the rest
            $_.Group | Select-Object -Skip 2 | Remove-Item -WhatIf
                
            break
        }
        
        {[datetime]$_.Name -lt $date.AddDays(-7) -and [datetime]$_.Name -ge $date.AddMonths(-3)}
        {
            # Groups which Date is lower than Date 7 Days ago and
            # greater than or equal to Date 3 Months ago
    
            # For this group (day), skip the first backup and
            # remove the rest
            $_.Group | Select-Object -Skip 1 | Remove-Item -WhatIf
                
            break
        }

        {[datetime]$_.Name -lt $date.AddMonths(-3) -and [datetime]$_.Name -ge $date.AddYears(-2)}
        {
            # Groups which Date is lower than Date 3 Months ago and
            # greater than or equal to Date 2 Years ago
                
            # Since this Group has more complexity than the others, 
            # will return this groups and store them in $onePerWeekGroups for later 
            return $_
        }

        Default
        {
            # Groups which Date is higher than 2 Years
                
            # For this group, remove everything
            Remove-Item -Path $_.Group.FullName -WhatIf
        }
    }
}
    
$calendar = (Get-Culture).Calendar
    
# Group all files by Year (Thanks Daniel for pointing this out)
# and by Week
$groupsPerWeek = $onePerWeekGroups.Group | Group-Object {
    $calendar.GetWeekOfYear(
        $_.CreationTime,
        [System.Globalization.CalendarWeekRule]::FirstFourDayWeek,
        [DayOfWeek]::Monday
    )}, {$_.CreationTime.Year}
    
foreach($group in $groupsPerWeek)
{
    # Skip the first file of this Week and Remove the rest
    $group.Group | Select-Object -Skip 1 | Remove-Item -WhatIf
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-12
    • 2013-04-17
    • 2023-04-10
    • 2015-12-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-13
    • 2016-07-27
    相关资源
    最近更新 更多