Создание файлового архива средствами PowerShell

A. Vasiliev делится решением проблемы по архивированию старых данных.
Все, наверное, знакомы с проблемой разрастающейся файлопомойки документации на файл сервере. У нас она выросла почти уже до 2 Тб. Чистка данного ресурса весьма затруднительна: отделы держатся за свои файлы как за самое святое, и их можно понять. Иногда приходится обращаться к файлам двух-трех годичной давности.

Однако держать такой объем информации – непозволительная роскошь хотя бы с точки зрения времени выполнения бэкапа и его восстановления.

Отсюда появилась задачка: создать файловый архив старых документов, обеспечить в него доступ только на чтение, обеспечить прозрачный доступ для пользователей.

Реализация, как всегда, моя любимая – скрипт на powershell.

Суть реализации – мы переносим файлы, которые давно не изменялись на другое хранилище (возможно более медленное и дешевое), а на месте удаленных файлов создаем ярлыки на новое местоположение. Для пользователя получается абсолютно прозрачный доступ. Он часто даже не видит разницы – ярлык называется также как и файл, значок такой же, открывается также по двойному клику. Т.к. файлы переносим с сохранением NTFS прав, доступ остается неизменным.

Сам скрипт выглядит следующим образом:

param (
$src, # источник
$dst, # место хранения архива
$daysold = 2*365, # насколько старые файлы переносить
$logfile = "log.txt"
)

$src = $src.TrimEnd(«\»)
$dst = $dst.TrimEnd(«\»)
echo «Starting at $(get-date)» > $logfile
# копируем иерархию каталогов с правами
#xcopy $src $dst /t /e /o /c /h /y
robocopy $src $dst /E /SEC /XF *.* /NDL
echo «Directory hierarchy copied» >> $logfile
$curdate = get-date
$Shell = new-Object -com Wscript.Shell
# по всем файлам, которые изменены ранее $daysold дней назад
$files = dir $src -recurse | where { ($_.Attributes -ne «Directory») -and ($_.Extension -ne «.lnk») -and (($curdate — $_.LastWriteTime).TotalDays -ge $daysold) }
$files | % {
write-progress -activity «Processing» -status $_.FullName
$file = $_
# будущее местоположение файла на архиве
$targetfilename = ($file.FullName -replace $src.Replace(«\»,»\\»),$dst)
# если файл еще не существует в архиве
if ( -not (test-path $targetfilename) ) {
# перемещаем файл
move $file.FullName $targetfilename
echo «Moved $($file.FullName) To $targetfilename» >> $logfile
# создаем на него ярлык
$link = $Shell.CreateShortcut(«$($file.FullName).lnk»)
$link.TargetPath = $targetfilename
$link.Save()
echo «Link $($link.FullName) created» >> $logfile
# выставляем права на ярлык (добавляем запрет на изменение и удаление)
$acl = Get-Acl $link.FullName
$addacl = New-Object System.Security.AccessControl.FileSystemAccessRule(«Everyone», «Delete,Write», «Deny»)
$acl.AddAccessRule($addacl)
Set-Acl $link.FullName $acl
echo «Link $($link.FullName) denied» >> $logfile
}
else {
echo «File $($file.FullName) already exist in archive» >> $logfile
}
}

Как заметили особо наблюдательные, код выставляет запрет на удаление и переименование (перемещение) ярлыка, дабы случайно не потерять драгоценную ссылку на файл для пользователя.
При помощи данного механизма нам удается держать размер и время выполнения бэкапа основной (оперативной) информации в приемлемых рамках.

Запись опубликована в рубрике Microsoft, Windows с метками . Добавьте в закладки постоянную ссылку.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *