Powershell 脚本删除最旧的文件(与当前日期无关)

Powershell 脚本删除最旧的文件(与当前日期无关)

不要想要“删除超过 X 天的文件”。如果我想这样做,我只需选择已经为此目的编写的数千个脚本中的一个,我不会在 ServerFault 上问这么简单的问题。

想要删除特定文件夹中除最近的 N 个文件之外的所有文件。

背景:远程系统配置为将定期存档文件转储到 Windows 服务器上的共享中。这些文件的命名约定为 YYYYMMDD-hhmm.ext。如果存档过程失败,我不希望清除脚本仅仅因为文件超过这么多天就删除它们。没有办法将远程系统配置为在存档过程中清除文件。

例如,当脚本运行时,文件夹中可能有 10 个文件,可能有 7 个文件,可能有 5 个文件。我需要始终保留至少最近的 5 个文件,无论它们有多旧。

可以用 PowerShell 完成这个吗?

编辑:最好忽略不符合命名约定的文件或文件夹。其他文件和文件夹不应被删除,也不应混淆脚本(导致保留少于 5 个存档文件)。

答案1

用法:yourScript.ps1 -Path path\to\run\against [-NumberToSave N]

param([String]$Path,[Int32]$NumberToSave=5)

$items = Get-ChildItem "$Path\*.ext" |
    Where-Object Name -match "\d\d\d\d\d\d\d\d-\d\d\d\d\.ext" |
    Sort-Object Name -Descending

if ($NumberToSave -lt $items.Count)
{
    $items[$NumberToSave..($items.Count-1)] | Remove-Item
}

我不认为这真的比@John 的更好,我只是为了尝试参数、正则表达式而不是使用循环而这样做的。执行正则表达式匹配确实可能有助于排除其他带有 .ext 的、与格式不匹配的文件(例如 20130504-1200.txt.ext、20.ext),但这是否适用值得怀疑。

我很沮丧地发现,如果 $NumberToSave = $items.Count,则需要 if 语句,否则它不会存在。从技术上讲:

$items[$numberToSave..$items.Count] | Remove-Item 

工作正常(如果引用超出数组边界,PowerShell 似乎不会出错,它只是处理并忽略它?)但这似乎可能会造成混淆。

答案2

$n = x

$items = Get-ChildItem path_to_folder\*.ext

$items | 
  Sort-Object Name -Descending | 
  Select-Object -Last ($items.count - $n) | 
  Foreach-Object { Remove-Item $_ }

答案3

# Get all the items in `C:\Archive`
Get-ChildItem -Path 'C:\Archive' |

    # Skip directories
    Where-Object { -not $_.PsIsContainer } |

    # Only get files that match YYYYMMDD-HHMM.ext format
    Where-Object { $_.Name -match '\d{8}-\d{4}.ext' } |

    # Sort them by name, from most recent to oldest
    Sort-Object -Descending -Property Name |

    # Keep the first five items
    Select-Object -Skip 5 |

    Remove-Item -WhatIf

答案4

这对我使用 powershell v5.1 有用

Get-ChildItem -Path C:\Path\To\Logs\BaseName*.log | Sort-Object -Descending | Select-Object -Skip 5 | Remove-Item

相关内容