2015-02-23 2 views
0

Я сделал Powershell скрипт, который следующийPowerShell: добавить дату и время в имени файла

$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" 
    } 
} 

Теперь это простой скрипт для удаления файлов из каталога.

У меня есть файлы в моем каталоге с именами, как этот

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 

теперь вы можете увидеть у нас есть два файла в 31th Jan 2015 и два файла в 5th Feb 2015. Я хочу, чтобы удалить все файлы, кроме двух последних добавлены и у нас есть время даты в имени файла видного

Update Я хочу оставить две новые файлы для каждой резервной копии базы данных

+0

Непонятно, что вы хотите сделать. Вы хотите оставить два новых файла в каталоге? Или два новых в день? Или что? –

+0

Я хочу оставить два новых – Ancient

+0

@MikeWise i обновленный вопрос, пожалуйста, см. – Ancient

ответ

1

Ваши временные метки неявны в именах файлов и в строко сортируемом формате, поэтому вам не нужно делать какие-либо манипуляции с дат-временем, чтобы найти самые новые. Получите файлы, сгруппированные по базе данных, затем для каждой базы данных сортируйте имена файлов в порядке убывания, и они будут в хронологическом порядке с новейшим в верхней части.

$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 } 
     } 
+0

Отлично !!!! снимаю перед вами шляпу . Большое спасибо – Ancient

1

Вы можете использовать следующий подход:

$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 
    } 
} 

кулак перебираемого все .bak файлы в каталоге.

В каждом из них мы рассмотрим имя файла, чтобы убедиться, что оно соответствует формату, и используйте регулярное выражение для извлечения имени базы данных и даты резервного копирования. [DateTime]::ParseExact можно использовать для создания объектов даты, которые он будет сравнивать с eaiser. Все эти свойства хранятся в PSCustomObject и добавляются в массив, так как мы можем использовать стандартные командлеты для фильтрации, сортировки и группировки списка.

Как только у нас есть массив объектов, мы можем сортировать их по дате резервного копирования и группировать их вместе. Затем мы можем перебирать группы и удалять все, кроме последних 2 файлов, так как это будут последние файлы для этой базы данных.

Если вы довольны сценарием, вы можете удалить параметр WhatIf в командлете Remove-Item, и файлы будут удалены вместо отображения того, что будет удалено.

Смежные вопросы