执行备份保留策略的脚本
Script to enforce backup retention policy
我需要一个脚本来查看我们的备份文件夹(我们对机器进行完整备份)并确保我们永远不会为每台计算机存储超过两个最近的备份。我目前正在研究一个 powershell 循环,该循环应该将每个文件名与备份文件夹中的每个其他文件进行比较。每台机器都有多个备份文件,可以通过匹配的前缀和由定界字符分隔的唯一 ID 号来识别。
prefix = 机器名称和唯一 ID 表示每个备份。
我正在努力将外环和 运行 设置到墙上。我正在 $array
中存储要检查的文件列表。
我有一个嵌套的 for 循环,我想根据数组中的每个其他文件检查每个文件。我有一个查询应该重建数组并在每次迭代时排除当前参考文件。
for ($i=0; $i -lt 5; $i++) {
$array = Get-ChildItem -路径 C:\Users\Aaron.Trujillo\Desktop\test
$array = Get-ChildItem -路径 C:\Users\Aaron.Trujillo\Desktop\test -排除 $array[$i]
for ($j=0; $j -lt 5; $j++){
Write-Host "i: $i j: $j"
Write-Host "Array i: $($array[$i].name) Array j: $($array[$j].name)"
if($array[$i].name -ne $array[$j].name)
{
Write-Host "truthval=false"
$truthval="false"
}
else
{
Write-Host "truthval=true"
$truthval = "true"
}
}
}
我期待这个循环将数组中的前五个文件相互比较(不包括当前参考文件)并更改每个文件的变量,但由于某种原因,参考文件没有被排除。
逻辑一定有问题,但我很难发现它。
我认为是 $array[$j.name]
周围的括号,即它应该是:
if($array[$i].name -ne $array[$j].name)
编辑:
要进行故障排除,请尝试手动输出您的信息:
for ($i=0; $i -lt 5; $i++) {
for ($j=$i+1; $j -lt 5; $j++){
Write-Host "i: $i j: $j"
Write-Host "Array i: $($array[$i].name) Array j: $($array[$j].name)"
if($array[$i].name -ne $array[$j].name)
{
Write-Host "truthval=false"
$truthval="false"
}
else
{
Write-Host "truthval=true"
$truthval = "true"
}
}
}
我发现你的代码有几个缺陷。
因为 $array
可能由 Get-ChildItem
填充(在 ntfs 格式的驱动器上 returns 一个 sorted 输出) 嵌套循环根本不是必需的。
当用一个进行迭代时,只需与 predessor/follower index +/- 1
.
进行比较
根据您的描述,名称包含一个 ID,因此它们总是不同的。所以你必须在模糊的分隔符处拆分名称并检查机器名称是否相同。
您的 if
命令不会发出任何内容,它只是在每次迭代时覆盖相同的变量。
有了 @Lee_Dailey 的分组好主意,您可以即时拆分名称并检查每组的计数,按 LastWriteTime 对每组的文件进行排序,并且只保留最新的 2.
所以给定一个假设的文件树
> tree /F
A:.
└───Backup
Alpha_8.bak
Bravo_2.bak
Bravo_5.bak
Bravo_6.bak
Bravo_7.bak
Bravo_9.bak
Charlie_1.bak
Charlie_10.bak
Charlie_3.bak
Charlie_4.bak
这个小脚本:
$BackupDir = 'A:\Backup'
$Delim = '_'
Get-ChildItem -Path $BackupDir -File |
Group-Object {($_.BaseName -split $Delim)[0]}
产量:
Count Name Group
----- ---- -----
1 Alpha {Alpha_8.bak}
5 Bravo {Bravo_2.bak, Bravo_5.bak, Bravo_6.bak, Bravo_7.bak...}
4 Charlie {Charlie_1.bak, Charlie_10.bak, Charlie_3.bak, Charlie_4.bak}
然后您可以通过任何方式迭代组并删除每个组的文件,
例如,删除每台机器除 2 个最新(根据 LastWriteTime 定义)文件外的所有文件:
Get-ChildItem -Path $BackupDir -File |
Group-Object {($_.BaseName -split $Delim)[0]} | ForEach-Object {
$_.Group | Sort LastWriteTime -Desc | Select -skip 2 | Remove-Item -WhatIf
}
如果输出看起来没问题,请删除尾随 -WhatIf
我需要一个脚本来查看我们的备份文件夹(我们对机器进行完整备份)并确保我们永远不会为每台计算机存储超过两个最近的备份。我目前正在研究一个 powershell 循环,该循环应该将每个文件名与备份文件夹中的每个其他文件进行比较。每台机器都有多个备份文件,可以通过匹配的前缀和由定界字符分隔的唯一 ID 号来识别。
prefix = 机器名称和唯一 ID 表示每个备份。
我正在努力将外环和 运行 设置到墙上。我正在 $array
中存储要检查的文件列表。
我有一个嵌套的 for 循环,我想根据数组中的每个其他文件检查每个文件。我有一个查询应该重建数组并在每次迭代时排除当前参考文件。
for ($i=0; $i -lt 5; $i++) {
$array = Get-ChildItem -路径 C:\Users\Aaron.Trujillo\Desktop\test $array = Get-ChildItem -路径 C:\Users\Aaron.Trujillo\Desktop\test -排除 $array[$i]
for ($j=0; $j -lt 5; $j++){
Write-Host "i: $i j: $j"
Write-Host "Array i: $($array[$i].name) Array j: $($array[$j].name)"
if($array[$i].name -ne $array[$j].name)
{
Write-Host "truthval=false"
$truthval="false"
}
else
{
Write-Host "truthval=true"
$truthval = "true"
}
}
}
我期待这个循环将数组中的前五个文件相互比较(不包括当前参考文件)并更改每个文件的变量,但由于某种原因,参考文件没有被排除。
逻辑一定有问题,但我很难发现它。
我认为是 $array[$j.name]
周围的括号,即它应该是:
if($array[$i].name -ne $array[$j].name)
编辑:
要进行故障排除,请尝试手动输出您的信息:
for ($i=0; $i -lt 5; $i++) {
for ($j=$i+1; $j -lt 5; $j++){
Write-Host "i: $i j: $j"
Write-Host "Array i: $($array[$i].name) Array j: $($array[$j].name)"
if($array[$i].name -ne $array[$j].name)
{
Write-Host "truthval=false"
$truthval="false"
}
else
{
Write-Host "truthval=true"
$truthval = "true"
}
}
}
我发现你的代码有几个缺陷。
因为
$array
可能由Get-ChildItem
填充(在 ntfs 格式的驱动器上 returns 一个 sorted 输出) 嵌套循环根本不是必需的。
当用一个进行迭代时,只需与 predessor/followerindex +/- 1
. 进行比较
根据您的描述,名称包含一个 ID,因此它们总是不同的。所以你必须在模糊的分隔符处拆分名称并检查机器名称是否相同。
您的
if
命令不会发出任何内容,它只是在每次迭代时覆盖相同的变量。
有了 @Lee_Dailey 的分组好主意,您可以即时拆分名称并检查每组的计数,按 LastWriteTime 对每组的文件进行排序,并且只保留最新的 2.
所以给定一个假设的文件树
> tree /F
A:.
└───Backup
Alpha_8.bak
Bravo_2.bak
Bravo_5.bak
Bravo_6.bak
Bravo_7.bak
Bravo_9.bak
Charlie_1.bak
Charlie_10.bak
Charlie_3.bak
Charlie_4.bak
这个小脚本:
$BackupDir = 'A:\Backup'
$Delim = '_'
Get-ChildItem -Path $BackupDir -File |
Group-Object {($_.BaseName -split $Delim)[0]}
产量:
Count Name Group
----- ---- -----
1 Alpha {Alpha_8.bak}
5 Bravo {Bravo_2.bak, Bravo_5.bak, Bravo_6.bak, Bravo_7.bak...}
4 Charlie {Charlie_1.bak, Charlie_10.bak, Charlie_3.bak, Charlie_4.bak}
然后您可以通过任何方式迭代组并删除每个组的文件,
例如,删除每台机器除 2 个最新(根据 LastWriteTime 定义)文件外的所有文件:
Get-ChildItem -Path $BackupDir -File |
Group-Object {($_.BaseName -split $Delim)[0]} | ForEach-Object {
$_.Group | Sort LastWriteTime -Desc | Select -skip 2 | Remove-Item -WhatIf
}
如果输出看起来没问题,请删除尾随 -WhatIf