Резервное копирование с помощью скриптов

Способов резервного копирования превеликое множество, но лично для меня они имеют свои минусы из-за которых я не использую их. Проще написать несколько простых скриптов, например, с помощью так называемого bat-ника или PowerShell. В этой статье я расскажу, как можно настроить резервное копирование с помощью скриптов, я их комбинирую и создаю связки.

Схема резервного копирования

В большинстве случаев backup сводится к сохранение неких файл. Это могут образы виртуальных машин, файлы пользователей, бекап базы SQL, выгрузка информационной базы 1С:Предприятие и т.д. Правильнее все эти резервные копии файлов хранить в другом месте, это может быть облачное хранилище owncloud, сетевая папка, внешний диск, ленточный накопитель, ftp и т.д. Из-за удобства я использую ftp сервер.

Давайте разберем схему как же это все происходит:

  1. Создаем сами архивные файлы
  2. Копируем или перемещаем их в папку для отправки в архив
  3. Проверяем папку на наличие в ней новых backup'ов
  4. Отправляем файлы в архив на FTP сервер
  5. Удаляем старые backup файлы

В первом пункте мы создали файлы, которые нам необходимо скопировать на наш FTP сервер. Теперь нам нужно скопировать их в папку, которую в свою очередь отправим на FTP. Для этого можно воспользоваться простой командой:

copy "ПУТЬ_К_ИСХОДНОЙ_ПАПКЕ\* C:\Backup\

Выполнив эту команды все наши файлы будут скопированы C:\Backup\. Выполнять данную команду имеет смысл, если Вы собираете из разных мест Ваши backup'ы. Теперь нам понадобится скрипт, который будет проверять папку на появление новых файлов и отправлять их на FTP сервер. Создаем пустой файл backup.ps1 и в него записываем следующий скрипт.

$a = (Get-Host).UI.RawUI
$a.WindowTitle = "Sync Folder To Ftp"
     
$ftp = "ftp://АДРЕС_FTP_СЕРВЕРА/"
$localDirectory = "C:\Backup"
$user = "ИМЯ_ПОЛЬЗОВАТЕЛЯ"
$pass = "ПАРОЛЬ"
     
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($user,$pass)

$Files = Get-ChildItem $localDirectory | Where {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} 
foreach ($File in $Files)
    {
        $LocalFile = $File.FullName

        Write-Host "Getting $File from $localDirectory" -Foreground "Red"

        $webclient.UploadFile($ftp + $File, $LocalFile) 

        Write-Host "Puting $File to $ftp" -Foreground "Yellow"
    } 
     
Write-Host "Finished Sync to $ftp" -Foreground "Green"

Давайте разберем как же работает данный скрипт. Сначало задаются переменные, в которых указывается сервер, имя пользователя, пароль, исходная папка. Затем в строке $Files = Get-ChildItem $localDirectory | Where {$_.LastWriteTime -gt (Get-Date).AddDays(-1)} делается выборка всех файлов, у которых дата изменения больше (-qt) чем текущая дата минус 1 день. Здесь можете подкорректировать под Ваше расписание. Я резервное копирование делаю каждый день. Затем в цикле мы проходим по каждому файлу, удовлетворяющему условия и отправляем его на FTP сервер.

Дабы не занимать место на диске, я удаляю бекапы старше 30 дней. В принципе, после отправки на FTP их можно тут же удалять, я оставляю их только для того что, если они вдруг понадобятся не пришлось бы тратить время на скачивание их с FTP, да и лишняя копия backup'ов не помешает, мало ли что может случится с FTP. Так что если место Вам позволяет, рекомендую хранить их и на исходном сервере.

Для очистки папки я использую скрипт removeOldBackups.ps1

$fullTargetPath = "C:\Backup"
$deleteFiles = Get-Childitem $fullTargetPath -Recurse | 
    Where {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | 
    Foreach { Remove-Item $_.FullName -Force -Recurse}

Крайне простой скрипт, поясню только одну строку Where {$_.LastWriteTime -lt (Get-Date).AddDays(-30)} | в этой строке сравнивается дата изменения файла с текущей датой минус 30 дней, под это сравнения попадут файлы у которых LastWriteTime меньше текущей даты минус 30 дней. При необходимости можете подправить под Ваши нужды.