VBS: Скрипт для удаления и архивации логов

Попался мне под руку очередной скрипт моего авторства. Сохраню его к себе на блог =)

Достаточно часто на серверах годами в папках с логфайлами собираются многочисленные файлы логов. В конце концов может закончится тем, что под эти файлы израсходуется большая часть дискового пространства, чаще всего такое случается на прокси серверах. Нужно контролировать такие папки. Скрипт, который периодически (например раз в 3 месяца) запускается, архивирует и удаляет файлы не изменявшиеся в течении какого-то отрезка времени (например последние три месяца), может облегчить работу администратору.

В своем древнем скрипте я архивирую файлы с помощью 7-zip, папку которого можно скопировать на сетевой ресурс и указать путь в строке:

ArchivatorPath = Chr(34) & "\\server\Public\Applications\7-Zip\7z" & Chr(34)

Ниже делюсь кодом 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
'Отмечу также, что если параметры содержат пробелы,
'в нашем случае это может быть путь к папке, то его надо
'брать в кавычки
'Автор: elims.org.ua

'объявление объектов
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 = 256
drive = ""
FileName = ""
Extension = ""
LogFile = ""
ArchivatorPath = Chr(34) & "\\io\Public\Applications\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
		WScript.Echo "List file of archiveng files: " & listfile
		Set LogTextStream = FSO.OpenTextFile(LogFile,8,1)
		LogTextStream.WriteLine "Starting Archiving: " & Now()
		LogTextStream.Close
		comand =  "cmd /c " & Chr(34) & ArchivatorPath & " a " & ArchiveType & ArchiveFile & " @" & Chr(34) & listfile & Chr(34) & " -scsWIN -mx9 -w"  & Chr(34) & path_work & Chr(34)
		WScript.Echo "command: " & comand
		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)
		Set LogTextStream = FSO.OpenTextFile(LogFile,8,1)
		LogTextStream.WriteLine "End Archiving: " & Now()
		LogTextStream.Close
	end if
	'если архивирование успешно - удаляем файлы и записываем это в лог
	Set TextStream = FSO.OpenTextFile(LogFile,8,1)
	if RetCode = 0 then
		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" EchoText = "Ошибка при архивации! Warning (Non fatal error(s)). For example, some files were locked by other application during compressing. So they were not compressed."
			Case "2" EchoText = "Ошибка при архивации! Fatal error"
			Case "7" EchoText = "Ошибка при архивации! Command line error"
			Case "8" EchoText = "Ошибка при архивации! Not enough memory for operation"
			Case "255" EchoText = "Ошибка при архивации! User stopped the process"
			Case "256" EchoText = "Ошибка при архивации! 7z не был запущен"
		End Select
		WScript.Echo EchoText
		TextStream.WriteLine  EchoText
	end if
	TextStream.Close
else
	WScript.Echo "files with specified mask is not found!"
end if

Сейчас смотрю на этот скрипт и понимаю что на Powershell он выглядел бы куда компактней. =)

Понравилось? =) Поделись с друзьями:

Обсудить