# Резервирование файлового сервера (v.2) # Создание архивных копий актуальных данных файлового сервера # Назначение переменной $s для исключения из пути-источника (используется далее) $s="D:\\fs\\" # Назначение переменной $spth - каталог скрипта (базовый) $spth = split-path -parent $MyInvocation.MyCommand.Definition # Назначение переменной $cA - Каталог с актуальными копиями (далее - 'A') $cA = "D:\fs\01-Общие\" # Назначение переменной $cB - Каталог постоянного хранения (далее - 'B') $cB = "\\domain\fs\08-Backup\01-B00\02-FS" # Назначение переменной $ht и $htD (путь и файл таблицы хешей) $ht="$spth\hashtable.csv" $htD="$spth\hashtable_dup.csv" # Создание комплексной переменной на основе даты (раздельные значения для "год"=$dt.y, "месяц"=$dt.m, "день"=$dt.d) $dt = New-Object PsObject -Property @{y=Get-date -f "yyyy"; m=Get-Date -f "MM"; d=Get-Date -f "dd"; f=Get-Date -f "yyyyMMdd"; h=Get-date -f "hh"; mm=Get-date -f "mm";} # ПО для выполнения архивации (7zip) $7z = "C:\Program Files\7-Zip\7z.exe" # Проверка существования и загрузка текущей таблицы хешей в массив $hta (создание массива в случае отсутсвия) if(Test-Path ($ht)) { [psobject[]]$hta=import-csv "$ht" -Encoding UTF8 } else { $hta=@() } # Проверка существования и загрузка текущей таблицы хешей дубликатов в массив $htb (создание массива в случае отсутсвия) if(Test-Path ($htD)) { [psobject[]]$htb=import-csv "$htD" -Encoding UTF8 } else { $htb=@() } # Создание полного списка файлов для хеширования и проверки $toCheck = Get-ChildItem $cA -R | where {! $_.PSIsContainer -eq $true} # Назначение функции Calc-Hash для хеширования Function Calc-Hash { Param ( [parameter(Position=0, Mandatory=$true, ValueFromPipeline=$false)] $file ) Begin { $md5 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider } Process { $hash = [System.BitConverter]::ToString($md5.ComputeHash([System.IO.File]::ReadAllBytes($file))) Write-Output $hash } } # Создание массива $toBackup из файлов к резервированию $toBackup=@() # Цикл создания хешей в массив $hta (в случае отсутсвия) и формирование списка файлов к резервированию Foreach ($f in $toCheck) { $h=Calc-Hash $f.FullName # Пропустить обработку текущего файла, если хэш не создан (например, изза недостатка прав) if (!($h)) { Write-Output "File '$f' Locked" | Out-File -filepath "$cB\locked.log" -encoding "UTF8" -Append Continue } $uid=($h+$f.FullName) if ($hta.hash -notcontains $h) { # Пополнение массива хешей (таблицы) новым уникальным значением $hta+=New-Object PsObject -Property @{hash=$h;file=$f.FullName;uid=$uid;} # Формирование списка файлов для резервирования с дополнительными параметрами (стандартные для файла + хеш) $toBackup+=$f | select @{n='Extension';e={$f.Extension}},@{n='FullName';e={$f.FullName}},@{n='BaseName';e={$f.BaseName}},@{n='Name';e={$f.Name}},@{n='Directory';e={$f.DirectoryName}},@{n='Hash';e={$h}} } elseif ($hta.uid -notcontains $uid) { if ($htb.uid -notcontains $uid) { # Назначение переменных для текущего и существующего файла $CurrentFile=$f.FullName $ExistFile=($hta -match $h).file # Переменная для лог-файла (полная дата и время) $dtf=$dt.y+"-"+$dt.m+"-"+$dt.d+" "+$dt.h+":"+$dt.mm $htb+=New-Object PsObject -Property @{hash=$h;fileA=$CurrentFile;fileB=$ExistFile;uid=$uid;} # Формирование лог-файла с сопоставлением дубликат = оригинал $duplog="$cB\dublicates.log" Write-Output "[$dtf] $CurrentFile = $ExistFile" | Out-File -filepath $duplog -encoding "UTF8" -Append } } } # Цикл резервирования файлов по списку массива $toBackup Foreach ($b in $toBackup) { # Формирование каталога размещения копии из замены $s в пути-источника на $cB (размещение идентично начальному, внутри каталога назначения) $bD=($b.Directory -replace $s,$cB) $bF=$bD+"\"+($b.Name) # Проверка существования каталога (создание, если отсутствует) if(!(Test-Path ($bD))) { md $bD } # Копирование файла # Проверка существование старой версии файла (архивация, если существует) if(Test-Path ($bF)) { # Назначение переменной для имени будущего архива $bFn=$bD+"\"+$b.BaseName+$b.Extension+"_"+$dt.f+".7z" # Архивация старой версии файла & $7z @('a','-t7z',$bFn,$bF) # Удалить старую версию файла Remove-Item $bF # Скопировать новую Copy-Item $b.FullName $bD } else { Copy-Item $b.FullName $bD } } # Выгрузить новые значения для таблиц с хешами архивированных файлов $hta | export-csv $ht -NoTypeInformation -Encoding UTF8 $htb | export-csv $htD -NoTypeInformation -Encoding UTF8