Isso removerá todos os arquivos com base na "chave" de cada pasta da empresa, exceto dois mais novos
A filtragem é baseada em LastWriteTimeUTC
Nesse código, a função $local:allFiles = @{};
in Filter-BackupFiles
é um valor-chave hastable, onde THE KEY faz parte do nome do arquivo antes de 12345_12345.bas
(a seleção fileKey
no RegEx, no meu exemplo, é tudo antes último símbolo _
) ans O VALOR é uma matriz de objetos de arquivo (não nomes de arquivo). Para cada arquivo eu adiciono (usando Add-Member
) um atributo para soring (no meu caso é LastWriteTimeUTC
, você pode fazer outra coisa no seu caso)
Em seguida, para cada chave (que é prefixo do nome do arquivo), classifico a lista de objetos de arquivo e adiciono à lista de remoção todos, exceto dois ( $Script:KeepMostRecent = 2
) primeiros arquivos (isso significa dois arquivos mais novos, porque foram ordenados por data).
$Script:StartPath = 'D:\Test_1'
$Script:KeepMostRecent = 2;
$Script:BackupSubfolder = 'backup'
$Script:RegexFilter = '^(?<fileKey>.*)_\d+_\d+\.bps$'
$Script:SimulatingMode = $true
#In my case regex is overriden because of file names
$Script:RegexFilter = '^(?<fileKey>.+)_[^_]+\.txt$' #THIS IS DEV OVERRIDE
Function Log-Error {
Param (
[Parameter(Mandatory=$true)]
[String]$LogMessage
)
Write-Host -ForegroundColor Yellow "Error: $($LogMessage)";
}
#End of Log-Error
Function Get-Companies {
Param (
[Parameter(Mandatory=$true)]
[String]$SearchBase
)
$local:companyDirectoies = @()
try {
$local:companyDirectoies = @(Get-ChildItem -Path $SearchBase -Recurse:$false -ErrorAction Stop | Where-Object {$_.psIsContainer -eq $true} -ErrorAction Stop | ForEach-Object {return $_.FullName} -ErrorAction Stop )
} catch {
Log-Error -LogMessage $([String]::Format("Error while getting companies list: {0}", $_.Exception.Message))
return $null
}
return $local:companyDirectoies
}
Function Get-BackupFiles {
Param (
[Parameter(Mandatory=$true)]
[String]$CompanyDirectoryPath
)
$local:files = @();
try {
$local:files = @( Get-ChildItem -Path $CompanyDirectoryPath -Recurse:$false -ErrorAction Stop | Where-Object {$_.psIsContainer -eq $false} -ErrorAction Stop)
} catch {
Log-Error -LogMessage $([String]::Format("Error while getting Backup file list for path {0}: {1}", $CompanyDirectoryPath ,$_.Exception.Message))
return $null
}
return $local:files
}
Function Filter-BackupFiles {
Param (
[Parameter(Mandatory=$true)]
[Object[]]$CompanyBackupFiles
)
$local:allFiles = @{};
$local:filesToRemove = @()
foreach ($local:f in $CompanyBackupFiles) {
$local:lastFileDate = $local:f.LastWriteTimeUtc
$local:f | Add-Member -MemberType NoteProperty -Name 'LastDate' -Value $( $local:lastFileDate )
$local:fileName = $local:f.Name
if ($local:fileName -match $Script:RegexFilter) {
$local:fileKey = $Matches['fileKey']
#Use NotCContains ir you need case-sensitive filtering
if ($local:allFiles.Keys -notcontains $local:fileKey) {
$local:allFiles[$local:fileKey] = @()
}
$local:allFiles[$local:fileKey] += @($local:f)
} else {
Log-Error -LogMessage $([String]::Format( "Error - the file name {0} does not match regEx. None will be processed for this list",$local:fileName))
return $null
}
}
foreach ($local:k in $local:allFiles.Keys) {
Write-Host -ForegroundColor White "Checking files for key $($local:k)"
$local:files = @( $local:allFiles[$local:k] | Sort-Object -Property 'LastDate' -Descending )
$local:filesToKeep = $Script:KeepMostRecent
foreach ($local:f in $local:files) {
$local:filesToKeep--
Write-Host -ForegroundColor White -NoNewline "$($local:f.FullName)'t$($local:f.LastDate)"
if ($local:filesToKeep -lt 0) {
$local:filesToRemove += @($local:f.FullName)
Write-Host -ForegroundColor Red "'tMARKED TO REMOVE"
} else {
Write-Host -ForegroundColor Green "'tMARKED TO LIVE"
}
}
}
return $local:filesToRemove
}
Function _main {
$local:AllFilesToRemove = @()
$local:companiesPathList = @(Get-Companies -SearchBase $Script:StartPath)
if ($local:companiesPathList.Count -le 0) {
Log-Error -LogMessage "Companies list is empty"
return
}
forEach ($local:comanyPath in $local:companiesPathList) {
Write-Host -ForegroundColor White "'r'n'r'nProcessing company on path $($local:comanyPath)"
$local:companyBackupFolder = ""
try {
$local:companyBackupFolder = $( Join-Path -Path $local:comanyPath -ChildPath $Script:BackupSubfolder -ErrorAction Stop )
$local:allCompanyFiles = Get-BackupFiles -CompanyDirectoryPath $local:companyBackupFolder -ErrorAction Stop
} catch {
Log-Error -LogMessage "Error getting backup files for company $($local:comanyPath) : $($_.Exception.Message)"
}
if (($local:allCompanyFiles.Count -le 0) -or ($local:allCompanyFiles -eq $null)) {
Log-Error -LogMessage "Company $($local:companyBackupFolder) does not have files in backup. Will ignore it."
continue
}
$local:companyFilesToRemove = Filter-BackupFiles -CompanyBackupFiles $local:allCompanyFiles
if (($local:companyFilesToRemove.Count -le 0) -or ($local:companyFilesToRemove -eq $null)) {
Write-Host -ForegroundColor Cyan "Company $($local:comanyPath) does not have files to remove. Will ignore it."
continue
}
Write-Host -ForegroundColor White "Company $($local:comanyPath) have $($local:companyFilesToRemove.Count) file to remove"
$local:AllFilesToRemove += @( $local:companyFilesToRemove )
}
Write-Host -ForegroundColor White "Totally we have $($local:AllFilesToRemove.Count) files to remove"
foreach ($local:f in $local:AllFilesToRemove) {
Write-Host -ForegroundColor White "Removing $($local:f)"
try {
Remove-Item -Path $local:f -Force -Confirm:$false -WhatIf:$Script:SimulatingMode -ErrorAction Stop
} catch {
Log-Error -LogMessage "Error removing file $($local:f) : $($_.Exception.Message)"
}
}
}
_main
Então a saída será
Processing company on path D:\Test_1\Company1
Checking files for key File1_Custom_Name
D:\Test_1\Company1\backup\File1_Custom_Name_bak1.txt 02/28/2016 07:07:38 MARKED TO LIVE
D:\Test_1\Company1\backup\File1_Custom_Name_Bak2.txt 02/28/2016 07:06:38 MARKED TO LIVE
D:\Test_1\Company1\backup\File1_Custom_Name_Bak3.txt 02/28/2016 07:05:38 MARKED TO REMOVE
Checking files for key File2
D:\Test_1\Company1\backup\File2_Bak1.txt 02/28/2016 07:07:38 MARKED TO LIVE
D:\Test_1\Company1\backup\File2_Bak2.txt 02/28/2016 07:06:38 MARKED TO LIVE
D:\Test_1\Company1\backup\File2_Bak3.txt 02/28/2016 07:05:38 MARKED TO REMOVE
Company D:\Test_1\Company1 have 2 file to remove
Processing company on path D:\Test_1\Company2
Checking files for key File2
D:\Test_1\Company2\backup\File2_Bak3.txt 02/28/2016 07:58:34 MARKED TO LIVE
D:\Test_1\Company2\backup\File2_Bak2.txt 02/28/2016 07:58:31 MARKED TO LIVE
D:\Test_1\Company2\backup\File2_Bak1.txt 02/28/2016 07:58:28 MARKED TO REMOVE
Checking files for key File4
D:\Test_1\Company2\backup\File4_Bak1.txt 02/28/2016 07:59:43 MARKED TO LIVE
D:\Test_1\Company2\backup\File4_Bak3.txt 02/28/2016 07:58:42 MARKED TO LIVE
D:\Test_1\Company2\backup\File4_Bak2.txt 02/28/2016 07:58:39 MARKED TO REMOVE
Checking files for key File1
D:\Test_1\Company2\backup\File1_Bak3.txt 02/28/2016 07:58:25 MARKED TO LIVE
D:\Test_1\Company2\backup\File1_Bak2.txt 02/28/2016 07:58:22 MARKED TO LIVE
D:\Test_1\Company2\backup\File1_bak1.txt 02/28/2016 07:58:17 MARKED TO REMOVE
Company D:\Test_1\Company2 have 3 file to remove
Processing company on path D:\Test_1\Company3
Checking files for key File2
D:\Test_1\Company3\backup\File2_Bak1.txt 02/28/2016 07:07:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File2_Bak2.txt 02/28/2016 07:06:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File2_Bak3.txt 02/28/2016 07:05:38 MARKED TO REMOVE
Checking files for key File4
D:\Test_1\Company3\backup\File4_Bak1.txt 02/28/2016 07:07:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File4_Bak2.txt 02/28/2016 07:06:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File4_Bak3.txt 02/28/2016 07:05:38 MARKED TO REMOVE
Checking files for key File1
D:\Test_1\Company3\backup\File1_bak1.txt 02/28/2016 07:07:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File1_Bak2.txt 02/28/2016 07:06:38 MARKED TO LIVE
D:\Test_1\Company3\backup\File1_Bak3.txt 02/28/2016 07:05:38 MARKED TO REMOVE
Company D:\Test_1\Company3 have 3 file to remove
Totally we have 8 files to remove
Removing D:\Test_1\Company1\backup\File1_Custom_Name_Bak3.txt
Removing D:\Test_1\Company1\backup\File2_Bak3.txt
Removing D:\Test_1\Company2\backup\File2_Bak1.txt
Removing D:\Test_1\Company2\backup\File4_Bak2.txt
Removing D:\Test_1\Company2\backup\File1_bak1.txt
Removing D:\Test_1\Company3\backup\File2_Bak3.txt
Removing D:\Test_1\Company3\backup\File4_Bak3.txt
Removing D:\Test_1\Company3\backup\File1_Bak3.txt