Skip to main content

Бэкапы MSSQL через скрипт PowerShell

При работе с 1С, когда база находится на SQL сервере, надо сделать так, чтоб у нас всегда была свежая резервная копия.
Это можно конечно сделать средствами самого MSSQL, но мы решили сделать скриптом на PowerShell. Код скрипта писал не я, а мой коллега. Однако код настолько прост, что я решил все-же его сохранить.

#Сколько дней хранить бэкап. AddDays(-1) означает 1 день, то есть вчерашний
$saveday = (Get-Date).AddDays(-1).ToString("yyyy.MM.dd")
#Список баз
$bases = "base1","base2"
#Удалить устаревшие бэкапы
foreach ($base in $bases)
{   
Remove-Item "C:\Backups\Files\$base\$saveday - $base.bak"
}

#Получаем текущую дату чтоб записать в имя
$date = Get-Date -format yyyy.MM.dd
#перебираем базы в списке и делаем их бэкапы, все бэкапы сразу кидаются в отдельную папку для базы, если у вас SQL EXPRESS то надо убрать  WITH COMPRESSION, INIT, NOFORMAT, SKIP, NOUNLOAD, это сжатие, которого нет в EXSPRESS
#SERVER-NAME - имя сервера, PASSW0RD - ну понятно
foreach ($base in $bases)
{ 
    $PathFile = "C:\Backups\Files\$base\$date - $base.bak" 
    sqlcmd -S SERVER-NAME -U sa -P "PASSW0RD" -Q "BACKUP DATABASE [$base] TO DISK = '$PathFile'  WITH COMPRESSION, INIT, NOFORMAT, SKIP, NOUNLOAD"
}

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

cd "C:\Backups\Scripts"
$date = Get-Date -format yyyy.MM.dd
#Перебираем базы в нашей директории
foreach ($base in $bases)
{   
    #смотрим есть ли файл за сегодня
    $CheckFile = Test-Path $PathFile
    #пытаемся выгрузить. -DD удалит после отправки, в цикле будем пытаться отправить, пока не уйдет с догрузкой. https://ncftp.com/ncftp/doc/ncftpput.html
	while($CheckFile -eq "True"){
		.\ncftpput.exe -z -r 10 -B 10000000 -S .tmp -DD -F -u "USER_FTP" -p 'PASSW0RD' -P 21 ftp.vlytkin.ru /backups/$base $PathFile
		Start-Sleep -s $waittime
		$try = $try + 1
		$CheckFile = Test-Path $PathFile
		if($try -eq $counttry ){
			break
		}
}
}

UPD: может быть так что код не работает, это связано с политиками на ПК
Чтоб оно заработало надо в PowerShell выполнить одну из команд (для ПК или для юзера) разрешающую выполнение нашего скрипта

Set-ExecutionPolicy RemoteSigned -Scope currentuser
Set-ExecutionPolicy RemoteSigned -Scope localmachine