|
Бакап файлов для малых предприятий
Вот кажется, одна из самых распростаненных задачек для администраторов или обслуживающего работника компьютерной сферы. Такое количество прилад написано, что просто уму непостижимо. Однако все таки встречаются моменты, когда из них приходится выкручиваться своими силами. Наверное, возможно приспособить что либо из уже написанного, но что-то мешает. Где-то можно закрыть глаза, а где-то вот не получается. Вот и я когда то давно столкнулся с такой задачей на малых предприятиях. Ну скажем, количество компьютеров 2-3, может 5. Или 7. Не суть. После 7-8 компании уже потихоньку переходят на сеть с выделенным сервером, ну или используют один из рабочих в качестве такого. Тогда задача меняется, и в данном случае не подходит и не рассматривается. Имеется ввиду как раз ситуация, когда несколько человек в конторе работают со своими данными и нечасто ими обмениваются. Бухгалтер работает с 1с базами, директор с договорами, менеджер с прайсами и прочей бумажно-электронной документацией. Ну это к примеру.
Есть ситуация, когда компьютеры все выключаются на ночь, и каждый имеет свой набор рабочей информации на компьютере, не очень большой по объему, но, возможно, большой по количеству небольших вордно-екселевских файликов. Вот для такой ситуации и была приспособлена такая система бакапов, которую я когда то делал в батиках а потом перевел на Vbscript. Опробована и работает она без вмешательства системщика, что как раз и имеет смысл при обслуживании маленьких фирм.
На первый взгляд, может быть, немного запутано. Может быть. Но это только на первый взгляд. Меня лично устраивает. Потому к делу. Понятно, что названия файлов, директорий, время выполнения могут быть любыми. Я просто пишу как пример. Имеет отношение к Виндам с 2000-й.
На компе с сохраняемой информацией (то есть на всех, где это нужно) через групповую политику компьютера стартует "backup_first.vbs". Он на основе информации из файла "backup_param.txt" делает копию информационной базы в c:\arxiv\....\ и сворачивет ее еще pkzip-ом в корневой каталог в файл Arx_....zip по дням недели. Для больших объемов работу архиватора можно отключить, дело вообщем-то хозяйское. Он же стартует через планировщик в 5:00 ночи на случай, если комп не выключат на ночь. То есть этот скрипт трудится, когда пользователь еще не работает за компьютером, что исключает столкновение с заблокированными файлами или изменяемыми на ходу базами данных. В папке назначения сначала сбрасываются атрибуты файлов, и, возможно удаляются (это если текучка файлов большая, чтобы не растить каталог назначения). Конечно, время загрузки компа увеличивается, и, некоторые вполне могут выпить кофе и обменяться последними сплетнями. Для маленьких компаний это чаще всего неактуально, а ценность информации в конкретных случаях бывает очень даже велика.
Поскольку сохранение информации на тот же винт есть суть бессмыслица, то:
На компе с сохраняемой информацией (то есть на всех, где это нужно) через групповую политику пользователя стартует "backup_second.vbs". Он на основе информации из файла "backup_param.txt" делает копию информационной базы из c:\arxiv\....\ (то есть уже копии, сделанной первым скриптом, простите за каламбур) на другой компьютер, определенный в "backup_param.txt". В процессе выполнения скрипта выполнеяется цикл, в котором опрашивается доступность компьютера назначения, и кружится цмкл каждые 10 минут в течении, ну сколько вам надо. Ведь комп назначения в этот день могут вообще не включить, тогда смотри на решение, принятое при планировании направлений копий. Как вариант, этот скрипт может стартовать, например, через планировщик в 10:00 утра и выполняться каждые полчаса в течении ... часов (цикл тогда лучше отключить). То есть скрипт выполняется, когда пользователь уже работает на компьютере и имеет открытые рабочие файлы. Но, поскольку копия то уже сделана, и там открытых файлов нет, это для нас уже не имеет значение. Имеет значение, что комп в это время теоретически может притормаживать, особенно если винт данного компа забит и фрагментирован. Но на практике - незаметно, из-за разницы скоростей работы сети и винта.
Есть еще третий скрипт, который заведует обменом информацией о прохождении бакапов с админом-настройщиком. Это зависит от полноты обслуживания конкретного предприятия, возможностей связи, бывает отличается от случая к случаю, и здесь не рассматривается. Но информация для него заложена.
То есть в результате мы получаем ежедневный перекрестный бакап с компа на комп, что выручает в случае гибели винта или компа - а это подавляющее количество случаев. Вариант, что одновременно выйдут из строя два компа с наборами информации и бакапом, редка, но что ж, в этом мире все бывает. Но, думаю, защита и от этого уже должна стоить денег. Если же работник сам запортил себе информацию, данный бакап тоже спасет, но пользователь чаще всего о таких бакапах и не знает и вообще должен ругать только себя (или платить). Конечно, набор данных у каждого пользователя может быть где угодно, и предусмотреть заранее невозможно, но чаще всего в таких случаях мы имеем дело с рабочим столом и моими документами. Плюс базы бухгалтерии.
Структура файла "backup_param.txt"
Параметры отделены точкой с запятой. в скриптах нумерация с 0-ля.
- 0 каталог назначения бакапа для "backup_first.vbs"
- 1 файл для записи лога сообщений бакапов
- 2 файл флага удачного копирования "backup_first.vbs", содержит дату
- 3 адрес для отсылки сообщений
- 4 значение для подстановки в поле «от кого»
- 5 значение для подстановки в поле «тема»
- 6 имя компьютера назначения для "backup_second.vbs"
- 7 список каталогов для копирования в "backup_first.vbs", разделен запятыми
Вот пример:
c:\arxiv\copy;c:\logcopy.log;c:\Flgcopy.log;vt436549@sms.samara-gsm.ru;avrora;arxiv;oplyas;c:\Inetpub\www,c:\Inetpub\ww,c:\Documents and Settings\user\Рабочий стол
Собственно, скрипт backup_first.vbs.
On Error Resume Next
' скрипт сделан 19.05.2005
' Денисов Виктор, Тольятти, v-vag@mail.ru.
strdipro = "c:\arxiv\bat\"
strfileparam = strdipro & "backup_param.txt"
Const OverWriteFiles = True
Const ForReading = 1
Dim WSHNetwork
Set WSHNetwork = WScript.CreateObject("WScript.Network")
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")
Dim Shell
Set Shell = WScript.CreateObject("WScript.Shell")
strCompname = WSHNetwork.ComputerName
Set objFileParam = objFSO.OpenTextFile(strfileparam, 1)
strParameters = objFileParam.Readline
sList = Split(strParameters, ";")
strdestfolder = sList(0) & "\"
strLogFile = sList(1)
strFLGFile = sList(2)
strnumber = sList(3)
strfrom = sList(4)
strSubject = sList(5)
strStringname = sList(7)
sListdir = Split(strStringname, ",")
objFileParam.Close
' -------- Обнуление атрибутов во всех подкаталогах в каталоге strdestfolderdel
Sub AttrSubfolders(strdestfolderdel)
Set f = objFSO.GetFolder(strdestfolderdel)
Set fc = f.SubFolders
If fc.Count = 0 Then
' -------- вызов подпрограммы для всех файлов если подкаталогов больше нет
ShowFiles f
f.attributes = 0
schfoldercount = schfoldercount + 1
Exit Sub
Else
For Each f1 in fc
' -------- рекурсивный вызов в подкаталоге
AttrSubfolders f1.path
' ------- вызов подпрограммы для всех файлов в подкаталоге
ShowFiles f
Next
End If
f.attributes = 0
schfoldercount = schfoldercount + 1
End Sub
' ---------- Обнуление атрибутов в каталоге Folder
Sub ShowFiles(Folder)
Set f2 = objFSO.GetFolder(Folder.Path)
Set fc2 = f2.Files
For Each f3 in fc2
f3.attributes = 0
schfilecount = schfilecount + 1
' errDeleteFile = f3.Delete
' If errDeleteFile > 0 Then flgerror = "yes"
Next
If flgerror = "yes" Then strerrordelete = "yes"
End Sub
Sub writeline(strfilewrite, strline)
Set objLogFile = objFSO.OpenTextFile (strfilewrite, 8, True)
objLogFile.WriteLine(strline)
objLogFile.Close
End Sub
Sub sendmail (strnumber, message)
On Error Resume Next
Set objEmail = CreateObject("CDO.Message")
objEmail.From = strfrom
objEmail.To = strnumber
objEmail.Subject = strSubject
objEmail.Textbody = message
objEmail.Send
On Error GoTo 0
End Sub
Sub timeoutprocess
'---------- ждем когда процесс закончится
numcircle = 0
WScript.Sleep 3000
Do
Set colProcesses = objWMIService.ExecQuery ("Select * from Win32_Process Where Name = 'pkzip25.exe'")
If colProcesses.Count = 0 Then
Exit Sub
Else
End If
WScript.Sleep 1000
numcircle = numcircle + 1
Loop Until numcircle > 1200
End Sub
'-------------- MAIN -----------------------------
Call writeline(strLogFile, "------------------------------------------------------------ FIRST ----- " & Now)
If objFSO.FileExists(strFLGFile) Then
Set objTextFile = objFSO.OpenTextFile(strFLGFile, 1)
strNextLine = objTextFile.Readline
If Trim(CStr(strNextLine)) = CStr(Date) Then
'------------------ флаг равен текущему дню, копирование было
Call writeline(strLogFile, Now & " - флаг равен текущему дню, копирование было, пропускаем")
Wscript.Quit
Else
Call writeline(strLogFile, Now & " - флаг копирования содержит другую дату, копируем")
End If
objTextFile.Close
Else
End If
flgerror = "no"
'-------------- сбрасываем атрибуты
AttrSubfolders(strdestfolder)
'-------------- начнем копирование
For each strsourcefolder in sListdir
err = objFSO.CopyFolder(strsourcefolder, strdestfolder, OverWriteFiles)
If err = 0 Then
Call writeline(strLogFile, Now & " - " & strsourcefolder & " - " & strdestfolder & " - OK copy")
Else
Call writeline(strLogFile, Now & " - " & strsourcefolder & " - " & strdestfolder & " - Ошибка копирования = " & err)
flgerror = "yes"
End If
Next
If flgerror = "yes" Then
Else
'---------------- запись флага копирования
If objFSO.FileExists(strFLGFile) Then objFSO.DeleteFile(strFLGFile)
Call writeline(strFLGFile, Date)
End If
If objFSO.FileExists(strdipro & "pkzip25.exe") Then
strrun = strdipro & "pkzip25.exe -add=update -rec -path=root c:\arx_" & Weekday(Date) & " " & strdestfolder & "*.* -temp=c:\"
Shell.run strrun
Call timeoutprocess
If numcircle > 1198 Then
Call writeline(strLogFile, Now & " ! - pkzip work more 20 minutes")
Else
End If
Else
End If
'WScript.Echo "end work script"
Собственно, скрипт backup_second.vbs.
On Error Resume Next
' скрипт сделан 19.05.2005
' Денисов Виктор, Тольятти, v-vag@mail.ru.
strdipro = "c:\arxiv\bat\"
strfileparam = strdipro & "backup_param.txt"
Const OverWriteFiles = True
Dim WSHNetwork
Set WSHNetwork = WScript.CreateObject("WScript.Network")
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim Shell
Set Shell = WScript.CreateObject("WScript.Shell")
sComp = WSHNetwork.ComputerName
Set objFileParam = objFSO.OpenTextFile(strfileparam, 1)
strParameters = objFileParam.Readline
sList = Split(strParameters, ";")
strsourcefolder = sList(0)
strLogFile = sList(1)
strFLGFile = sList(2)
strnumber = sList(3)
strfrom = sList(4)
strSubject = sList(5)
strdestComp = sList(6)
strdestfolder = "\\" & strdestComp & "\arxiv\" & sComp & "\"
strFileProv = "\\" & strdestComp & "\arxiv\bat\pkzip25.exe"
strStringname = sList(7)
sListdir = Split(strStringname, ",")
objFileParam.Close
Sub writeline(strfilewrite, strline)
Set objLogFile = objFSO.OpenTextFile (strfilewrite, 8, True)
objLogFile.WriteLine(strline)
objLogFile.Close
End Sub
Sub sendmail (strnumber, message)
On Error Resume Next
Set objEmail = CreateObject("CDO.Message")
objEmail.From = strfrom
objEmail.To = strnumber
objEmail.Subject = strSubject
objEmail.Textbody = message
objEmail.Send
On Error GoTo 0
End Sub
Call writeline(strLogFile, "------------------------------------------------------------ SECOND ---- " & Now)
strCompname = WSHNetwork.ComputerName
If objFSO.FileExists(strFLGFile) Then
Call writeline(strLogFile, Now & " - flag copy OK, go last")
numcircle = 0
Do
If objFSO.FileExists(strFileProv) Then
Call writeline(strLogFile, Now & " - " & strdestComp & " - access , go last")
err = objFSO.CopyFolder(strsourcefolder, strdestfolder, OverWriteFiles)
If err = 0 Then
Call writeline(strLogFile, Now & " - " & strsourcefolder & " - " & strdestfolder & " - OK copy to other computer")
' objFSO.DeleteFile(strFLGFile)
' полезно, если комп после перезагрузки должен выполнить еще копирование
Else
Call writeline(strLogFile, Now & " - " & strsourcefolder & " - " & strdestfolder & " - Ошибка копирования = " & err)
flgerror = "yes"
End If
Exit Do
Else
End If
WScript.Sleep 600000
numcircle = numcircle + 1
Loop Until numcircle > 60
Else
End If
'WScript.Echo "end work script"
|