Когда-то давно мною был написан vbs-скрипт, сейчас он попался под руку и я решил его опубликовать. Чтоб не затерялся в недрах винчестеров.
Скрипт архивирует файлы (по маске), которые не модифицировались по прошествии указанного количества дней/месяцев. С помощью этого скрипта можно автоматизировать процесс архивирования лог-файлов, которые накапливаются в служебных папках, - экономия занятого пространства, да и папка при открытии не будет тормозить если в ней не находятся тысячи или десятки тысяч файлов. Файлы архивируются с помощью архиватора 7zip (7-zip.org), который сохранен на доступном для всех серверов сетевом диске, там же сохранены и сами скрипты.
Сейчас просматривая этот скрипт я вижу где и что можно было бы оптимизировать, но помня поговорку "Не надо трогать то, что хорошо работает", решил ничего не менять.
Итак, скрипт отвечающий за архивацию:
'данный скрипт delmask.vbs удаляет в директории все файлы, у которых
'дата последней модификации старше определенного количества дней
'синтаксис таков
'delmask.vbs /a:<address with mask> /d:<days> /r /l:<File Name> /e:<File Name> /7z
'/a:<address with mask> - адрес папки с маской файла
'/d:<number> - указывает старше скольки дней файлы будут удаляться
'/m:<number> - указывает старше скольки месяцев файлы будут удаляться
'/r - использовать рекурсию ВНИМАНИЕ! значительно замедляется работа скрипта
'/l:<File Name> - ведение лога
'/e:<File Name> - закидывать удаляемые файлы в архив, по умолчанию тип - zip
'/7z - архивироватся будет в формате 7zip, использовать параметрв вместе с /e:<File Name>
'например
'delmask.vbs /a:c:\0\*.txt /d:8 /r /l:C:\log.log /e:archive.zip
'Отмечу также, что если параметры содержат пробелы,
'в нашем случае это может быть путь к папке, то его надо
'брать в кавычки
'обьявление обьектов
set objNamedArgs=Wscript.Arguments.Named
Set objDateTime = CreateObject("WbemScripting.SWbemDateTime")
Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\CIMV2")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("Wscript.Shell")
'справка
if (objNamedArgs.Exists("?")) then
WScript.Echo "данный скрипт удаляет в директории все файлы, у которых"
WScript.Echo "дата последней модификации старше определенного количества дней"
WScript.Echo "синтаксис таков"
WScript.Echo "del.vbs /a:<address with mask> /d:<days> /r /l:<File Name> /e:<File Name>"
WScript.Echo "/a:<address with mask> - адрес папки с маской файла"
WScript.Echo "/d:<number> - указывает старше скольки дней файлы будут удаляться"
WScript.Echo "/m:<number> - указывает старше скольки месяцев файлы будут удаляться" кот
WScript.Echo "/r - использовать рекурсию ВНИМАНИЕ! значительно замедляется работа скрипта"
WScript.Echo "/l:<File Name> - ведение лога"
WScript.Echo "/e:<File Name> - закидывать удаляемые файлы в архив"
WScript.Echo "например"
WScript.Echo "del.vbs /a:c:\0\*.txt /d:8 /r /l:C:\log.log /e:archive.zip"
WScript.Echo "Отмечу также, что если параметры содержат пробелы, "
WScript.Echo "в нашем случае это может быть путь к папке, то его надо "
WScript.Echo "брать в кавычки"
WScript.Quit
end if
RetCode = 0
drive = ""
FileName = ""
Extension = ""
LogFile = ""
ArchivatorPath = Chr(34) & "\\networkdisk\Scripts\7-Zip\7z" & Chr(34)
ArchiveFile = ""
ArchiveType = "-tzip "
zip7 = ""
strdate = Year(date)
if Month(date) < 10 then strdate = strdate & "0" & Month(date) else strdate = strdate & Month(date) end if
if Day(date) < 10 then strdate = strdate & "0" & Day(date) else strdate = strdate & Day(date) end if
'вычисляем время последней модификации
if (objNamedArgs.Exists("d")) then
killdate=DateAdd("d",-objNamedArgs.item("d"),date)
end if
if (objNamedArgs.Exists("m")) then
killdate=DateAdd("m",-objNamedArgs.item("m"),date)
end if
path=objNamedArgs.item("a")
LogFile = objNamedArgs.item("l")
if (objNamedArgs.Exists("e")) then
ArchiveFile = Chr(34) & objNamedArgs.item("e") & strdate & Chr(34)
end if
if (objNamedArgs.Exists("7z")) then
if not(objNamedArgs.Exists("e")) then
WScript.Echo "Вы не указали имя архива, используйте параметр /e"
WScript.Quit
end if
ArchiveType = "-t7z "
end if
objDateTime.SetVarDate killdate
if killdate = "" then
WScript.Echo "Вы не указали время"
WScript.Quit
else
WScript.Echo "Будут удалены файлы, которые созданы до " & killdate
end if
'коректировка sql запроса
path=Replace(path, "*", "%")
path=Replace(path, "?", "_")
'разделение адреса на диск, папку, имя-маску, раширение-маску файла
slash = InStrRev(path,"\")
FileName = Mid(path,slash+1)
tochka = InStrRev(FileName,".")
drive=Left(path,2)
path = Left(path,slash)
path=Mid(path,3)
path_work = drive & path
if tochka <> 0 then
Extension = Mid(FileName,tochka+1)
FileName = Mid(FileName,1,tochka-1)
end if
listfile = path_work & "listfile.txt"
if ( drive = "" ) or ( FileName = "" ) then
WScript.Echo "неверно введенная маска!"
WScript.Quit
end if
'заменяем все одинарные слешы на двойные
path=Replace(path, "\", "\\")
'проверяем надо ли рекурсию
if (objNamedArgs.Exists("r")) then
podzapros = "Path Like'" & path & "%'"
else
podzapros = "Path = '" & path & "'"
end if
zapros = "SELECT Name, LastModified FROM CIM_DataFile WHERE Drive = '" & drive & "' AND " & podzapros & " AND FileName Like '" & FileName & "' AND LastModified <= '" & objDateTime.value & "'"
'Смотрим если в маске файла расширение
if Extension <> "" then
zapros = zapros & " AND Extension Like '" & Extension & "'"
end if
On Error Resume Next
If Err.Number <> 0 Then
WScript.Echo Err.Number & ": " & Err.Description
WScript.Quit
End If
'выполняем запрос
Set colFiles = objService.ExecQuery(zapros)
'если запрос выдал не нулевой результат
if colFiles.Count <> 0 then
'если надо архивировать - архивируем
if ( ArchiveFile <> "" ) then
Set TextStream = FSO.CreateTextFile(listfile,1)
For Each objFile In colFiles
TextStream.WriteLine Chr(34) & objFile.Name & Chr(34)
Next
TextStream.Close
comand = "cmd /c " & Chr(34) & ArchivatorPath & " a " & ArchiveType & ArchiveFile & " @" & Chr(34) & listfile & Chr(34) & " -scsWIN -mx9 -w" & Chr(34) & path_work & Chr(34)
if LogFile <> "" then
comand = comand & " >> " & Chr(34) & LogFile & Chr(34)
end if
comand = comand & Chr(34)
RetCode = WshShell.Run(comand, 0, True)
FSO.DeleteFile(listfile)
end if
'если архивирование успешно - удаляем файлы и записуем это в лог
if RetCode = 0 then
Set TextStream = FSO.OpenTextFile(LogFile,8,1)
For Each objFile In colFiles
WScript.Echo objFile.Name
objDateTime.Value = objFile.LastModified
TextStream.WriteLine "Delete File " & Now() & " " & objFile.Name & " " & objDateTime.GetVarDate
FSO.DeleteFile(objFile.Name)
Next
WScript.Echo "Завершено успешно! Всего файлов: " & colFiles.Count
'если архивирование не успешно - выдаем ошибку
else
Select Case RetCode
Case "1" WScript.Echo "ошибка при архивации! Warning (Non fatal error(s)). For example, some files were locked by other application during compressing. So they were not compressed."
Case "2" WScript.Echo "ошибка при архивации! Fatal error"
Case "7" WScript.Echo "ошибка при архивации! Command line error"
Case "8" WScript.Echo "ошибка при архивации! Not enough memory for operation"
Case "255" WScript.Echo "ошибка при архивации! User stopped the process"
End Select
end if
TextStream.Close
else
WScript.Echo "files with specified mask is not found!"
end ifЗапуск этого скрипта я совершаю из скрипта №2:
Set WSHShell = CreateObject("WScript.Shell")
Set WshSysEnv = WshShell.Environment("Process")
Set FSO = CreateObject("Scripting.FileSystemObject")
strdate = Year(date)
if Month(date) < 10 then strdate = strdate & "0" & Month(date) else strdate = strdate & Month(date) end if
if Day(date) < 10 then strdate = strdate & "0" & Day(date) else strdate = strdate & Day(date) end if
if WshSysEnv("ComputerName") = "NAME_OF_SERVER" then
comand = "cscript \\networkdisk\Scripts\delmask.vbs /a:" & Chr(34) & "C:\Program Files\Microsoft Forefront Threat Management Gateway\Logs\*.w3c" & Chr(34) & " /m:1 /e:" & Chr(34) & "C:\Program Files\Microsoft Forefront Threat Management Gateway\Logs\Archive\archive" & Chr(34) & " /l:" & Chr(34) & "C:\Program Files\Microsoft Forefront Threat Management Gateway\Logs\Archive\log.log" & Chr(34)
RetCode = WshShell.Run(comand, 0, True)
FSO.CopyFile "C:\Program Files\Microsoft Forefront Threat Management Gateway\Logs\Archive\archive" & strdate & ".zip", "\\networkdisk\Public\Backup\NameOfServer\Logs\"
FSO.CopyFile "C:\Program Files\Microsoft Forefront Threat Management Gateway\Logs\Archive\log.log", "\\networkdisk\Public\Backup\NameOfServer\Logs\"
end ifСама суть автоматизации такова: в скрипте №2 (который сохранен на сетевом диске) я описываю для каждого сервера какие папки и файлы необходимо архивировать (а значит с какими параметрами необходимо запустить скрипт №1). После этого в планировщике задач каждого сервера добавляю задачу с запуском скрипта №2. Если мне нужно архивировать файлы которые старше 3-х месяцев, то и задача эта выполняется раз в три месяца.
С помощью условий
if WshSysEnv("ComputerName") = "NAME_OF_SERVER" then
скрипт узнает на каком сервере он запущен и дает команду скрипту №1 на архивацию тех или иных папок.
Таким образом в одном файле-скрипте перечислены все папки логов всех серверов в нашей сети - удобно для анализа архивируемых папок, редактирования скрипта и добавления одной универсальной команды в планировщики задач всех серверов.