Всем привет!
Отчёт о том, что запускает пользователь на своём компьютере, крайне важен. С многих точек зрения. Особенно с точки зрения информационной безопасности.
Информация о запуске программ на компьютерах пользователей храниться в журнале безопасности. Конечно, рассматривается среда Windows. В Инете готового решения не нашёл, поэтому сделал свою реализацию.
Скрипт запускается на сервере. На выходе имеем набор файлов с отчётами о запуске программ.
Картинка для привлечения внимания:
Основная идея такая. Текущие события журнала безопасности сохраняются в evt-файле на клиентском компьютере. Файл копируется на сервер, где информация из него загружается на SQL Server. Затем SQL-запросом формируется отчёт и сохраняется в файл.
Теперь, как это реализовано.
Необходимо создать папки Log, Logs, CheckComps, Logi_ForReports и Computer. У меня папки на диске F. В папке Log создать файл list.txt со списком компьютеров, которые необходимо проверить. Каждое имя компьютера с новой строки. Я создал 2 файла list.txt и list7.txt для XP и семёрок соответственно. В папке Computer создать файл is_computer_online_listComps.vbs
on error resume next
dim gsFileName
dim gsRunCmd
dim gix
dim giy
dim giz
if Wscript.Arguments.Count = 1 then
gsFileName = Wscript.Arguments(0)
gsOS = "XP"
elseif Wscript.Arguments.Count = 2 then
gsFileName = Wscript.Arguments(0)
gsOS = Wscript.Arguments(1)
else
gsFileName = InputBox("Файл со списком компьютеров", "Ввод", "F:Loglist.txt")
gsOS = InputBox("Тип операционной системы:" & VBNewLine & "'XP' - для Windows 2000/XP" & VBNewLine & "'7' - для Windows 7", "Ввод", "XP")
end if
gsOS = uCase(gsOS)
wscript.echo "gsOS: " & gsOS
if inStr(gsOS, "XP") = 0 and inStr(gsOS, "7") = 0 then
MsgBox "Некорректно указан тип операционной системы!", vbInformation, "Внимание"
Wscript.Quit
end if
WScript.Echo "Файл со списком компьютеров: " & gsFileName
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFileOpen = objFSO.OpenTextFile(gsFileName, 1)
gix = 0
giy = 0
Set WshShell = CreateObject("WScript.Shell")
do until objTextFileOpen.AtEndOfStream
gsComputerName = objTextFileOpen.Readline
giy = giy + 1
loop
objTextFileOpen.Close
wscript.echo "Найдено компьютеров: " & giy
Set objTextFileOpen = objFSO.OpenTextFile(gsFileName, 1)
do until objTextFileOpen.AtEndOfStream
gsComputerName = objTextFileOpen.Readline
gix = gix + 1
giz = gix * 100
giz = giz / giy
giz = Round(giz, 1)
giOst = giy - gix
if fuPing(gsComputerName) then
wscript.echo gsComputerName & VBTab & " осталось: " & giOst & ", готово: " & giz & "%"
if inStr(gsOS, "XP") then
gsRunCmd = "f:Computeris_computer_online.bat " & gsComputerName & " y"
elseif inStr(gsOS, "7") then
gsRunCmd = "f:Computeris_computer_online7.bat " & gsComputerName & " y"
end if
WshShell.Run gsRunCmd
if giOst <> 0 then
WScript.Sleep 180000 ' Внимание! Вот это задержка в 180 секунд между компьютерами.
end if
else
wscript.echo gsComputerName & VBTab & " осталось: " & giOst & ", готово: " & giz & "%. Выключен."
end if
loop
objTextFileOpen.Close
WScript.Echo "Операция завершена!"
function fuPing(NetworkDevice)
lBoo = false
set objPING = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery ("select * from Win32_PingStatus where address ='" & NetworkDevice & "'")
For Each PING In objPing
if PING.StatusCode = 0 then
'WScript.Echo "* Компьютер " & NetworkDevice & " в сети!"
lBoo = true
else
'WScript.Echo "* Компьютера нет в сети."
end if
next
fuPing = lBoo
end function
Запускается процедура проверки bat-файлом. Ссылку на него можно сделать, например, на рабочем столе.
cscript //nologo "f:Computeris_computer_online_listComps.vbs" %1 %2
Основной скрипт is_computer_online_listComps.vbs читает список компьютеров из текстового файла и для каждого запускает bat-файл формирования отчёта. Для XP — это файл is_computer_online.bat, для 7 — is_computer_online7.bat.
Примечание.
На сервере нужно установить logparser.
Всё описанное должно заработать и на компьютере администратора. Только надо установить Microsoft SQL SERVER 2008 NATIVE CLIENT и Microsoft SQL Server 2008 Command Line Utilities. Но я не проверял.
Блок работы с компьютерами XP
Bat-файл:
cscript //nologo "f:Computeris_computer_online.vbs" %1 %2
Bat-файл запускает скрипт. Скрипт выполняет сохранение событий журнала безопасности в evt-файл и запускает основной батник mo2csv.bat.
on error resume next
dim gsComputerName
dim gsUseLogFile
dim gsLogFilename
dim gbFlag
dim gsTableName
dim gsCompName
dim gsRunCmd
if Wscript.Arguments.Count = 1 then
gsComputerName = Wscript.Arguments(0)
gsUseLogFile = "n"
elseif Wscript.Arguments.Count = 2 then
gsComputerName = Wscript.Arguments(0)
gsUseLogFile = Wscript.Arguments(1)
else
gsComputerName = InputBox("Имя компьютера", "Введите", "")
gsUseLogFile = InputBox("Использовать log-файл для проверки?" & VBNewline & "[y/n]", "Введите", "y")
end if
WScript.Echo "* Имя компьютера " & gsComputerName
gsLogFilename = "f:Log" & gsComputerName & ".log"
if lCase(gsUseLogFile) = "y" then
gbFlag = false
WScript.Echo "* Файл журнала " & gsLogFilename
set objFSO = CreateObject("Scripting.FileSystemObject")
if not objFSO.FileExists(gsLogFilename) then
WScript.Echo "* Файла журнала нет. Создается..."
set objTextFileWriteLog = objFSO.OpenTextFile(gsLogFilename, 8, True)
objTextFileWriteLog.writeLine "n"
objTextFileWriteLog.close
WScript.Echo "* Создан успешно."
end if
set objTextFileOpen = objFSO.OpenTextFile(gsLogFilename, 1)
do until objTextFileOpen.AtEndOfStream
record = trim(objTextFileOpen.Readline)
if record = "n" then
WScript.Echo "* Компьютер не проверялся ранее."
if fuPing(gsComputerName) then
gbFlag = true
if fuBackup(gsComputerName) then
WScript.Sleep 15000 ' <- 15 секунд задержки для бекапа
fuUploadEvents gsComputerName
wscript.sleep 10000
end if
end if
elseif record = "y" then
WScript.Echo "* Информация с компьютера " & gsComputerName & " уже закачана на сервер."
else
WScript.Echo "* Некорректная информация о компьютере " & gsComputerName & " в log-файле."
end if
loop
objTextFileOpen.close
if gbFlag then
set objTextFileWriteLog = objFSO.OpenTextFile(gsLogFilename, 2, True)
objTextFileWriteLog.writeLine "y"
objTextFileWriteLog.close
WScript.Echo "* Информация записана в журнал."
end if
else
'if fuPing(gsComputerName) then
if fuBackup(gsComputerName) then
WScript.Sleep 15000 ' <- 15 секунд задержки для бекапа
fuUploadEvents gsComputerName
wscript.sleep 10000
end if
'end if
end if
wscript.sleep 1000
function fuPing(NetworkDevice)
lBoo = false
set objPING = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery ("select * from Win32_PingStatus where address ='" & NetworkDevice & "'")
For Each PING In objPing
if PING.StatusCode = 0 then
WScript.Echo "* Компьютер " & NetworkDevice & " в сети!"
lBoo = true
else
WScript.Echo "* Компьютера нет в сети."
end if
next
fuPing = lBoo
end function
function fuBackup(lsComputername)
lsEvtBackupFilename = "c:" & lsComputername & ".evt"
lsEvtBackupFilenameRemote = "\" & lsComputername & "c$" & lsComputername & ".evt"
lbFlag = false
set lObjFSO = CreateObject("Scripting.FileSystemObject")
if lObjFSO.FileExists(lsEvtBackupFilenameRemote) then
WScript.Echo "* Файл журнала уже есть. Используем существующий..."
lbFlag = true
else
Wscript.Echo "* Выполняется резервное копирование..."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(Backup)}!\" & lsComputername & "rootcimv2")
Set colLogFiles = objWMIService.ExecQuery ("Select * from Win32_NTEventLogFile where LogFileName='Security'")
For Each objLogfile in colLogFiles
errBackupLog = objLogFile.BackupEventLog(lsEvtBackupFilename)
If errBackupLog = 0 Then
Wscript.Echo "* Резервное копирование выполнено успешно."
lbFlag = true
Else
Wscript.Echo "* Резервное копирование не выполнено."
End If
Next
end if
fuBackup = lbFlag
end function
function fuUploadEvents(lsComputername)
WScript.Echo "* Запущена закачка на сервер..."
gsCompName = lCase(lsComputername)
gsTableName = fuGetTableName(gsCompName)
gsTableName = uCase(gsTableName)
gsOutputFilename = "f:Computer" & gsCompName & ".csv"
gsOutputFilenameSQL = "f:Computer" & gsCompName & "_sql.csv"
Set WshShell = CreateObject("WScript.Shell")
gsRunCmd = "f:Computermo2csv.bat " & gsCompName & " " & gsOutputFilename & " " & gsOutputFilenameSQL & " " & gsTableName
WScript.Echo "* Выполняется команда: '" & gsRunCmd & "'"
WshShell.Run gsRunCmd
end function
function fuGetTableName(lsCompName)
lsTmp = lsCompName
if InStr(lsTmp, "-") then
lsTmp = Replace(lsTmp, "-", "_")
end if
fuGetTableName = lsTmp
end function
mo2csv.bat делает следующее:
- Забирает evt-файл с удалённого компьютера на сервер.
- Преобразовывает evt-файл в evtx.
- Выгружает только события запуска/остановки программ из evtx-файла в текстовый файл csv.
- Информацию из текстового файла закачивает на SQL Server.
- Бекапит оригинальный evt-файл в папку Logi_ForReports (вдруг пользователь сотрёт свой журнал, а у нас копия есть).
- Удаляет временный evtx-файл.
- Формирует и выполняет sql-запрос к SQL Server’у.
- Удаляет временные файлы (в случае отладки или для изучения работы скрипта, этот раздел можно закомментировать).
- Перемещает отчёты в папку CheckComps.
@echo off
@set WDate=%date:~-10%
@echo * Журнал безопасности перемещается с удаленного компьютера %1 (Windows XP)...
move \%1c$%1.evt f:Logs
@echo * Перемещение завершено.
@echo * Выполняется конвертация evt журнала в evtx...
wevtutil epl f:Logs%1.evt f:Logs%1.evtx /lf:true
@echo * Конвертация завершена.
@echo * Информация из журнала безопасности выгружается в текстовый файл. Источник: f:Logs%1.evtx, назначение: %2
LogParser.exe file:"f:Computerget_info_from_log.sql"?source=f:Logs%1.evtx+output_file=%2 -i:EVT -o:TSV -headers:ON -oSeparator:tab -oTsFormat:"dd.MM.yyyy hh:mm:ss" -fileMode:1
@echo * Выгрузка завершена.
@echo * Исправляю текстовый файл %2. Получаю %3...
cscript F:Computerupdate_csvFile_forSQLCheck.vbs %2 %3 //NoLogo
@echo * Исправление завершено.
@echo * Информация из текстового файла закачивается на SQL Server. Источник: %3, таблица %4...
LogParser.exe file:"f:Computerget_info_from_log_2SQL.sql"?source=%3+output_file=%4 -i:TSV -headerRow:ON -iSeparator:tab -iTsFormat:"dd.MM.yyyy hh:mm:ss" -o:SQL -server:"SQL-SRVSEC" -database:quickly -driver:"SQL Server" -createTable:ON
@echo * Процесс завершен.
@echo * Журнал безопасности перемещается в архив...
move f:Logs%1.evt f:Logi_ForReports%1_%WDate%_sec.evt
@echo * Перемещение завершено. Имя архивного файла 'f:Logi_ForReports%1_%WDate%_sec.evt'
@echo * Удаление временного evtx журнала...
del f:Logs%1.evtx
@echo * Удаление завершено.
@echo * Создание sql-запроса...
cscript "F:Computercreate_SQL_full.vbs" %1 1 //nologo
@echo * Создание завершено.
@echo * Выполнение sql-запроса...
SQLCMD.EXE -S SQL-SRVSEC -d quickly -E -i f:Computer%1-1.sql -o "f:Computer%1. Запуск программ.csv" -W -R -s ";" -w 4000
@echo * Выполнение завершено.
@echo * Исправляю результирующие файлы отчетов...
cscript F:Computerupdate_result_file.vbs "f:Computer%1. Запуск программ.csv" //nologo
@echo * Исправление завершено.
@echo * Удаление временных файлов...
del f:Computer%1-1.sql
del %2
del %3
del f:Computer%1_dbg.txt
del "f:Computer%1. Запуск программ.csv"
@echo * Удаление завершено.
@echo * Перемещение файлов-отчетов...
move "f:Computer%1. Запуск программ.xls" "f:CheckComps%1. Запуск программ.xls"
@echo * Перемещение завершено.
@echo on
Примечание
Возможно, в батнике нужно будет SQLCMD.EXE заменить на «c:Program FilesMicrosoft SQL Server100ToolsBinnSQLCMD.EXE», а LogParser.exe на «c:Program Files (x86)Log Parser 2.2LogParser.exe» (или «c:Program FilesLog Parser 2.2LogParser.exe»).
Имя сервера с SQL Server’ом SQL-SRV, имя экземпляра SEC и имя базы quickly. Заменить на свои.
SELECT RecordNumber as id,
eventid as eId,
TimeGenerated as Tg,
resolve_sid(sid) as UserName,
computername as Computer,
EXTRACT_TOKEN(Strings, 0, '|') as image_unique_id,
EXTRACT_TOKEN(Strings, 1, '|') as image
into %output_file%
FROM %source%
where ((EventID in (592; 593))
and (TO_UPPERCASE(resolve_sid(sid)) <> 'NT AUTHORITYNETWORK SERVICE')
and (TO_UPPERCASE(resolve_sid(sid)) <> 'NT AUTHORITYSYSTEM'))
and TimeGenerated >= TO_TIMESTAMP('01.03.2011 00:00:00','dd.MM.yyyy hh:mm:ss')
order by recordnumber asc
SELECT *
into %output_file%
FROM %source%
On Error Resume Next
dim gsSimbolSplitFields
dim sgSimbolSplitAdmin
dim gbInsideBlock
dim gIx
dim gbDebug
dim gbWriteString
Dim gArrBlock_admin
gsSimbolSplitFields = vbTab
sgSimbolSplitAdmin = ";"
gbInsideBlock = false
gbIERuning = false
gbIE = false
giBlockPlus = 0
giIEPlus = 0
gsDateBlock = "01.01.2011 00:00:00"
TgBlockStop = "01.01.2011 00:00:00"
idBlockStop = ""
gIx = 0
gArrBlock_admin = Array (sgSimbolSplitAdmin & sgSimbolSplitAdmin, _
sgSimbolSplitAdmin & sgSimbolSplitAdmin, _
sgSimbolSplitAdmin & sgSimbolSplitAdmin, _
sgSimbolSplitAdmin & sgSimbolSplitAdmin)
gbDebug = true
'gbDebug = false
if Wscript.Arguments.Count = 1 then
sgFilename = Wscript.Arguments(0)
sgFilenameOut = fuRemoveExtention(sgFilename) & "_sql.csv"
gsLogFilename = fuRemoveExtention(sgFilename) & "_dbg.txt"
elseif Wscript.Arguments.Count = 2 then
sgFilename = Wscript.Arguments(0)
sgFilenameOut = Wscript.Arguments(1)
gsLogFilename = fuRemoveExtention(sgFilename) & "_dbg.txt"
elseif Wscript.Arguments.Count = 3 then
sgFilename = Wscript.Arguments(0)
sgFilenameOut = Wscript.Arguments(1)
gsLogFilename = Wscript.Arguments(2)
else
sgFilename = InputBox("Имя исходного файла", "Введите", "f:comp-6475.csv")
sgFilenameOut = InputBox("Имя результирующего файла", "Введите", fuRemoveExtention(sgFilename) & "_sql.csv")
gsLogFilename = InputBox("Имя файла журнала", "Введите", fuRemoveExtention(sgFilename) & "_dbg.txt")
end if
Set objFSO = CreateObject("Scripting.FileSystemObject")
if not objFSO.FileExists(sgFilename) then
wscript.echo "Исходного файла для обновления нет, выхожу!"
Wscript.Quit
end if
Set objTextFileOpen = objFSO.OpenTextFile(sgFilename, 1)
Set objTextFileWrite = objFSO.CreateTextFile(sgFilenameOut, True)
if gbDebug then
if not objFSO.FileExists(gsLogFilename) then
set objTextFileWriteLog = objFSO.OpenTextFile(gsLogFilename, 8, True)
else
set objTextFileWriteLog = objFSO.CreateTextFile(gsLogFilename, True)
end if
end if
Do Until objTextFileOpen.AtEndOfStream
record = trim(objTextFileOpen.Readline)
gIx = gIx + 1
gbWriteString = true
fuPrint gIx & ". '" & record & "'"
if InStr(record, gsSimbolSplitFields) then
arr = Split(record, gsSimbolSplitFields)
id = arr(0)
eId = arr(1)
Tg = arr(2)
UserName = arr(3)
Computer = arr(4)
image_unique_id = arr(5)
image = arr(6)
if InStr(lCase(image), "explorer.exe") then
if eId = "592" then
gbBlockBegin = true
gbBlockEnd = false
giBlockPlus = giBlockPlus + 1
fuPrint "explorer.exe старт"
else
gbBlockBegin = false
gbBlockEnd = true
giBlockPlus = giBlockPlus - 1
if giBlockPlus < 0 then
giBlockPlus = 0
end if
fuPrint "explorer.exe стоп"
end if
else
gbBlockBegin = false
gbBlockEnd = false
end if
if InStr(lCase(image), "iexplore.exe") then
gbIE = true
fuPrint "Строка с iexplore.exe"
if eId = "592" then
fuPrint "iexplore.exe старт"
giIEPlus = giIEPlus + 1
gbIERuning = true
if giIEPlus = 1 then
image_unique_idIEStart = image_unique_id
end if
else
fuPrint "iexplore.exe стоп"
giIEPlus = giIEPlus - 1
gbIERuning = false
end if
else
gbIE = false
fuPrint "Строка без iexplore.exe"
end if
if gIx = 1 then
objTextFileWrite.WriteLine record & gsSimbolSplitFields & "CompStart"
fuPrint "Первая строка, записываем"
elseif gIx = 2 then
fuPrint "вторая строка"
if gbBlockBegin then
fuPrint "Начало блока, записываем"
gbInsideBlock = true
gsDateBlock = Tg
gsUserNameBlockStart = UserName
image_unique_idBlockStart = image_unique_id
objTextFileWrite.WriteLine record & gsSimbolSplitFields & gsDateBlock
end if
idPrev = id
eIdPrev = eId
TgPrev = Tg
UserNamePrev = UserName
ComputerPrev = Computer
image_unique_idPrev = image_unique_id
imagePrev = image
else
'fuPrint "остальные строки"
'-- Запуск explorer.exe
if gbBlockBegin then
fuPrint "Запуск explorer.exe (экземпляр № " & giBlockPlus & ")"
if giBlockPlus = 1 then
giDiff = DateDiff("s", CDate(TgBlockStop), CDate(Tg))
if giDiff > 9 then
if Len(idBlockStop) > 0 then
fuPrint "Это не перезапуск explorer.exe. Записываем остановку предыдущего блока"
record_convert_prev = idBlockStop & gsSimbolSplitFields & _
eIdBlockStop & gsSimbolSplitFields & _
TgBlockStop & gsSimbolSplitFields & _
UserNameBlockStop & gsSimbolSplitFields & _
ComputerBlockStop & gsSimbolSplitFields & _
image_unique_idBlockStart & gsSimbolSplitFields & _
imageBlockStop & gsSimbolSplitFields & _
gsDateBlock
fuPrint record_convert_prev
objTextFileWrite.WriteLine record_convert_prev
end if
gsDateBlock = Tg
fuPrint "Новая дата блока: '" & gsDateBlock & "'"
image_unique_idBlockStart = image_unique_id
fuPrint "Новый код блока: '" & image_unique_idBlockStart & "'"
gsUserNameBlockStart = UserName
fuPrint "Новый пользователь блока: '" & gsUserNameBlockStart & "'"
else
fuPrint "Это перезапуск explorer.exe! Не записываем остановку предыдущего блока и не записываем запуск этого."
gbWriteString = false
end if
gbInsideBlock = true
else
if lCase(gsUserNameBlockStart) = lCase(UserName) then
fuPrint "gsUserNameBlockStart: '" & gsUserNameBlockStart & "', UserName: '" & UserName & "'"
fuPrint "Начало блока. Возможно, компьютер был аварийно выключен. Необходимо записать окончание предыдущего блока и сохранить новые параметры блока"
record_convert_prev = "999" & gsSimbolSplitFields & _
"593" & gsSimbolSplitFields & _
Tg & gsSimbolSplitFields & _
UserName & gsSimbolSplitFields & _
Computer & gsSimbolSplitFields & _
image_unique_idBlockStart & gsSimbolSplitFields & _
"C:WINDOWSexplorer.exe" & gsSimbolSplitFields & _
gsDateBlock
fuPrint record_convert_prev
objTextFileWrite.WriteLine record_convert_prev
giBlockPlus = 1
gsDateBlock = Tg
fuPrint "Новая дата блока: '" & gsDateBlock & "'"
image_unique_idBlockStart = image_unique_id
fuPrint "Новый код блока: '" & image_unique_idBlockStart & "'"
else
'fuPrint "gsUserNameBlockStart: '" & gsUserNameBlockStart & "', UserName: '" & UserName & "'"
fuPrint "Не начало блока. Возможно, администратор запустил explorer. Записать текущую строку и сохранить параметры"
gArrBlock_admin(giBlockPlus-2) = image_unique_id & sgSimbolSplitAdmin & UserName & sgSimbolSplitAdmin & Tg
fuPrint gArrBlock_admin(giBlockPlus-2)
'gsDateBlock_admin = Tg
objTextFileWrite.WriteLine record & gsSimbolSplitFields & Tg
gbWriteString = false
end if
end if
end if
'-- Остановка explorer.exe
if gbBlockEnd then
fuPrint "Остановлен explorer.exe (осталось экземпляров " & giBlockPlus & ")"
if giBlockPlus = 0 then
fuPrint "Остановлен последний экземпляр, сохраняем его значения"
idBlockStop = id
eIdBlockStop = eId
TgBlockStop = Tg
UserNameBlockStop = UserName
ComputerBlockStop = Computer
image_unique_idBlockStop = image_unique_id
imageBlockStop = image
gbInsideBlock = false
giIEPlus = 0 ' <-- Добавил для обнуления количества копий IE
else
fuPrint "Остановлен не последний экземпляр, его значения не сохраняем, только записываем текущую строку"
for giY = 0 to UBound(gArrBlock_admin)
arrA = Split(gArrBlock_admin(giY), sgSimbolSplitAdmin)
gsImage_unique_id_A = arrA(0)
gsUserName_A = arrA(1)
gsTg_A = arrA(2)
if gsImage_unique_id_A = image_unique_id then
gsDateBlock_admin = gsTg_A
end if
next
objTextFileWrite.WriteLine record & gsSimbolSplitFields & gsDateBlock_admin
gbWriteString = false
end if
end if
'-- Записать текущую строку
if gbInsideBlock then
if gbIE then
if (((gbIERuning) and (giIEPlus = 1)) or ((not gbIERuning) and (giIEPlus = 0))) then
fuPrint "Записать IE строку"
record_convert_prev = id & gsSimbolSplitFields & _
eId & gsSimbolSplitFields & _
Tg & gsSimbolSplitFields & _
UserName & gsSimbolSplitFields & _
Computer & gsSimbolSplitFields & _
image_unique_idIEStart & gsSimbolSplitFields & _
image & gsSimbolSplitFields & _
gsDateBlock
fuPrint record_convert_prev
objTextFileWrite.WriteLine record_convert_prev
else
fuPrint "Вот хрень с IE! gbIERuning: " & gbIERuning & ", giIEPlus: " & giIEPlus
record_convert_prev = id & gsSimbolSplitFields & _
eId & gsSimbolSplitFields & _
Tg & gsSimbolSplitFields & _
UserName & gsSimbolSplitFields & _
Computer & gsSimbolSplitFields & _
image_unique_idIEStart & gsSimbolSplitFields & _
image & gsSimbolSplitFields & _
gsDateBlock
fuPrint record_convert_prev
end if
else
if gbWriteString then
fuPrint "Текущая строка в блоке и ее нужно записать"
fuPrint record & gsSimbolSplitFields & gsDateBlock
objTextFileWrite.WriteLine record & gsSimbolSplitFields & gsDateBlock
else
fuPrint "Текущая строка в блоке, но ее записывать не нужно"
end if
end if
else
fuPrint "Текущая строка не в блоке. Не записываем"
end if
'-- Сохранить текущие значения параметров для следующего прохода
idPrev = id
eIdPrev = eId
TgPrev = Tg
UserNamePrev = UserName
ComputerPrev = Computer
image_unique_idPrev = image_unique_id
imagePrev = image
end if
end if
fuPrint "----------------------------------------------"
Loop
objTextFileWrite.Close
objTextFileOpen.Close
if gbDebug then
objTextFileWriteLog.close
end if
WScript.Echo ""
WScript.Echo "* Операция успешно завершена."
function fuRemoveExtention(lsFilename)
lRes = lsFilename
if InStr(lsFilename, ".") then
lRes = Left(lsFilename, Len(lsFilename)-4)
end if
fuRemoveExtention = lRes
end function
function fuGetDateFromFullDate(lsFullDate)
lRes = lsFullDate
if InStr(lsFullDate, " ") then
lArr = Split(lsFullDate, " ")
lsDate = lArr(0)
lsTime = lArr(1)
lRes = lsDate
end if
fuGetDateFromFullDate = lRes
end function
function fuGetTimeFromFullDate(lsFullDate)
lRes = lsFullDate
if InStr(lsFullDate, " ") then
lArr = Split(lsFullDate, " ")
lsDate = lArr(0)
lsTime = lArr(1)
lRes = lsTime
end if
fuGetDateFromFullDate = lRes
end function
function fuPrint(lsStr)
'if gbDebug then
' wscript.echo lsStr
'end if
if gbDebug then
objTextFileWriteLog.writeLine lsStr
end if
fuPrint = true
end function
if Wscript.Arguments.Count = 1 then
gsComputerName = Wscript.Arguments(0)
gsSQLtype = "1"
elseif Wscript.Arguments.Count = 2 then
gsComputerName = Wscript.Arguments(0)
gsSQLtype = Wscript.Arguments(1)
else
gsComputerName = InputBox("Имя компьютера", "Введите", "")
gsSQLtype = InputBox("Тип sql-запроса?" & VBNewline & "[1 - короткий, 2 - полный, 3 - оба]", "Введите", "1")
end if
set objFSO = CreateObject("Scripting.FileSystemObject")
if gsSQLtype = "1" then
fuCreateSQLFile gsComputerName, "1"
elseif gsSQLtype = "2" then
fuCreateSQLFile gsComputerName, "2"
elseif gsSQLtype = "3" then
fuCreateSQLFile gsComputerName, "1"
fuCreateSQLFile gsComputerName, "2"
end if
function fuGetTableName(lsCompName)
lsTmp = lsCompName
if InStr(lsTmp, "-") then
lsTmp = Replace(lsTmp, "-", "_")
end if
fuGetTableName = lsTmp
end function
sub fuCreateSQLFile(lsComputerName, lsSQLtype)
if lsSQLtype = "1" then
lsTemplateFilename = "f:Computertemplate-short.sql"
elseif gsSQLtype = "2" then
lsTemplateFilename = "f:Computertemplate-full.sql"
end if
lsLogFilename = "f:Computer" & lsComputerName & "-" & lsSQLtype & ".sql"
lsTableName = fuGetTableName(lsComputerName)
if not objFSO.FileExists(lsLogFilename) then
set objTextFileWriteLog = objFSO.OpenTextFile(lsLogFilename, 8, True)
else
set objTextFileWriteLog = objFSO.OpenTextFile(lsLogFilename, 2, True)
end if
Set objTextFileOpen = objFSO.OpenTextFile(lsTemplateFilename, 1)
do until objTextFileOpen.AtEndOfStream
record = objTextFileOpen.Readline
if InStr(record, "WARNING__TABLE_NAME_FOR_CHANGE") then
record = Replace(record, "WARNING__TABLE_NAME_FOR_CHANGE", lsTablename)
end if
objTextFileWriteLog.writeLine record
loop
objTextFileOpen.Close
objTextFileWriteLog.Close
end sub
SELECT TOP (100) PERCENT Computer AS [Имя компьютера], UserName AS [Учетная запись], image AS Программа, start_time AS [Время запуска],
stop_time AS [Время завершения], dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) / 3600))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 / 60))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 % 60)) AS Длительность
FROM (SELECT r.Computer, r.UserName, r.image_unique_id, r.image, r.Tg AS start_time, MIN(s.Tg) AS stop_time
FROM (SELECT id, eId, Tg, UserName, Computer, image_unique_id, image
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 592) AND (Tg > CONVERT(DATETIME, '2013-01-01 00:00:00.000', 102))
) AS r INNER JOIN
(SELECT id, eId, Tg, UserName, Computer, image_unique_id, image
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 593)) AS s ON r.image_unique_id = s.image_unique_id AND r.image = s.image AND r.id < s.id AND r.Tg <= s.Tg
GROUP BY r.UserName, r.Computer, r.image_unique_id, r.image, r.Tg) AS DERIVEDTBL
ORDER BY 'Время запуска' DESC
if Wscript.Arguments.Count = 1 then
gsFileName = Wscript.Arguments(0)
gsFileNameRes = fuRemoveExtention(gsFileName) & ".xls"
elseif Wscript.Arguments.Count = 2 then
gsFileName = Wscript.Arguments(0)
gsFileNameRes = Wscript.Arguments(1)
else
gsFileName = InputBox("Файл для обновления", "Ввод", "")
gsFileNameRes = InputBox("Файл результата", "Ввод", fuRemoveExtention(gsFileName) & ".xls")
end if
sgSimbolSplit = ";"
gsSimbolSplitFields = vbTab
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFileOpen = objFSO.OpenTextFile(gsFileName, 1)
if not objFSO.FileExists(gsFileName) then
wscript.echo "Исходного файла для обновления нет, выхожу!"
objTextFileOpen.Close
Wscript.Quit
end if
if not objFSO.FileExists(gsFileNameRes) then
set objTextFileWriteRes = objFSO.OpenTextFile(gsFileNameRes, 8, True)
else
set objTextFileWriteRes = objFSO.CreateTextFile(gsFileNameRes, True)
end if
do until objTextFileOpen.AtEndOfStream
record = objTextFileOpen.Readline
if ((InStr(record, "--------")) or (Len(record) = 0) or (InStr(record, "обработано строк")) or (InStr(record, "rows affected"))) then
'wscript.echo "пропускаю строку: '" & record & "'"
else
if InStr(record, sgSimbolSplit) then
recordRes = Replace(record, sgSimbolSplit, gsSimbolSplitFields)
else
recordRes = record
end if
objTextFileWriteRes.writeLine recordRes
end if
loop
objTextFileWriteRes.Close
objTextFileOpen.Close
WScript.Echo "Обновление завершено! Результирующий файл " & gsFileNameRes
function fuRemoveExtention(lsFilename)
lRes = lsFilename
if InStr(lsFilename, ".") then
lRes = Left(lsFilename, Len(lsFilename)-4)
end if
fuRemoveExtention = lRes
end function
Блок работы с компьютерами с семёркой
Bat-файл:
cscript //nologo "f:Computeris_computer_online7.vbs" %1 %2
Bat-файл запускает скрипт. Скрипт выполняет сохранение событий журнала безопасности в evt-файл и запускает основной батник mo7.bat.
on error resume next
dim gsComputerName
dim gsUseLogFile
dim gsLogFilename
dim gbFlag
dim gsTableName
dim gsCompName
dim gsRunCmd
if Wscript.Arguments.Count = 1 then
gsComputerName = Wscript.Arguments(0)
gsUseLogFile = "n"
elseif Wscript.Arguments.Count = 2 then
gsComputerName = Wscript.Arguments(0)
gsUseLogFile = Wscript.Arguments(1)
else
gsComputerName = InputBox("Имя компьютера", "Введите", "")
gsUseLogFile = InputBox("Использовать log-файл для проверки?" & VBNewline & "[y/n]", "Введите", "y")
end if
WScript.Echo "* Имя компьютера " & gsComputerName
if lCase(gsUseLogFile) = "y" then
gbFlag = false
gsLogFilename = "f:Log" & gsComputerName & ".log"
WScript.Echo "* Файл журнала " & gsLogFilename
set objFSO = CreateObject("Scripting.FileSystemObject")
if not objFSO.FileExists(gsLogFilename) then
WScript.Echo "* Файла журнала нет. Создается..."
set objTextFileWriteLog = objFSO.OpenTextFile(gsLogFilename, 8, True)
objTextFileWriteLog.writeLine "n"
objTextFileWriteLog.close
WScript.Echo "* Создан успешно."
end if
set objTextFileOpen = objFSO.OpenTextFile(gsLogFilename, 1)
do until objTextFileOpen.AtEndOfStream
record = trim(objTextFileOpen.Readline)
if record = "n" then
WScript.Echo "* Компьютер не проверялся ранее."
if fuPing(gsComputerName) then
'fuListInstalledSoftware gsComputerName
gbFlag = true
if fuBackup(gsComputerName) then
WScript.Sleep 15000 ' <- 15 секунд задержки для бекапа
fuUploadEvents gsComputerName
wscript.sleep 10000
end if
end if
elseif record = "y" then
WScript.Echo "* Информация с компьютера " & gsComputerName & " уже закачана на сервер."
else
WScript.Echo "* Некорректная информация о компьютере " & gsComputerName & " в log-файле."
end if
loop
objTextFileOpen.close
if gbFlag then
set objTextFileWriteLog = objFSO.OpenTextFile(gsLogFilename, 2, True)
objTextFileWriteLog.writeLine "y"
objTextFileWriteLog.close
WScript.Echo "* Информация записана в журнал."
'MsgBox "Компьютер " & gsComputerName & " в сети!", vbInformation, "Внимание"
end if
else
'if fuPing(gsComputerName) then
if fuBackup(gsComputerName) then
WScript.Sleep 15000 ' <- 15 секунд задержки для бекапа
fuUploadEvents gsComputerName
wscript.sleep 60000
end if
'end if
end if
wscript.sleep 1000
function fuPing(NetworkDevice)
lBoo = false
set objPING = GetObject("winmgmts:{impersonationLevel=impersonate}")._
ExecQuery ("select * from Win32_PingStatus where address ='" & NetworkDevice & "'")
For Each PING In objPing
if PING.StatusCode = 0 then
WScript.Echo "* Компьютер " & NetworkDevice & " в сети!"
lBoo = true
else
WScript.Echo "* Компьютера нет в сети."
end if
next
fuPing = lBoo
end function
function fuBackup(lsComputername)
lsEvtBackupFilename = "c:" & lsComputername & ".evt"
lsEvtBackupFilenameRemote = "\" & lsComputername & "c$" & lsComputername & ".evt"
lbFlag = false
'WScript.Echo "* lsEvtBackupFilename: " & lsEvtBackupFilename
'WScript.Echo "* lsEvtBackupFilenameRemote: " & lsEvtBackupFilenameRemote
set lObjFSO = CreateObject("Scripting.FileSystemObject")
if lObjFSO.FileExists(lsEvtBackupFilenameRemote) then
WScript.Echo "* Файл журнала уже есть. Используем существующий..."
lbFlag = true
else
Wscript.Echo "* Выполняется резервное копирование..."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate,(Backup)}!\" & lsComputername & "rootcimv2")
Set colLogFiles = objWMIService.ExecQuery ("Select * from Win32_NTEventLogFile where LogFileName='Security'")
For Each objLogfile in colLogFiles
errBackupLog = objLogFile.BackupEventLog(lsEvtBackupFilename)
If errBackupLog = 0 Then
Wscript.Echo "* Резервное копирование выполнено успешно."
lbFlag = true
Else
Wscript.Echo "* Резервное копирование не выполнено."
End If
Next
end if
fuBackup = lbFlag
end function
function fuUploadEvents(lsComputername)
WScript.Echo "* Запущена закачка на сервер..."
gsCompName = lCase(lsComputername)
gsTableName = fuGetTableName(gsCompName)
gsTableName = uCase(gsTableName)
Set WshShell = CreateObject("WScript.Shell")
gsRunCmd = "f:Computermo7.bat " & gsCompName & " " & gsTableName
WScript.Echo "* Выполняется команда: '" & gsRunCmd & "'"
WshShell.Run gsRunCmd
end function
function fuGetTableName(lsCompName)
lsTmp = lsCompName
if InStr(lsTmp, "-") then
lsTmp = Replace(lsTmp, "-", "_")
end if
fuGetTableName = lsTmp
end function
mo7.bat делает следующее:
- Забирает evt-файл с удалённого компьютера на сервер.
- Преобразовывает evt-файл в evtx.
- Информацию из evtx-файла закачивает на SQL Server.
- Бекапит оригинальный evt-файл в папку Logi_ForReports (вдруг пользователь сотрёт свой журнал, а у нас копия есть).
- Удаляет временный evtx-файл.
- Формирует и выполняет sql-запрос к SQL Server’у.
- Удаляет временные файлы (в случае отладки или для изучения работы скрипта, этот раздел можно закомментировать).
- Перемещает отчёты в папку CheckComps.
@echo off
@set WDate=%date:~-10%
@echo * Журнал безопасности перемещается с удаленного компьютера %1 (Windows 7)...
move \%1c$%1.evt f:Logs
@echo * Перемещение завершено.
@echo * Выполняется конвертация evt журнала в evtx...
wevtutil epl f:Logs%1.evt f:Logs%1.evtx /lf:true
@echo * Конвертация завершена.
@echo * Информация из журнала безопасности закачивается на сервер. Источник: f:Logs%1.evtx
LogParser.exe file:"f:Computerget_info_from_log7.sql"?source=f:Logs%1.evtx+output_file=%2 -i:EVT -o:SQL -server:"SQL-SRVSEC" -database:quickly -driver:"SQL Server" -createTable:ON
@echo * Процесс завершен.
@echo * Журнал безопасности перемещается в архив...
move f:Logs%1.evt f:Logi_ForReports%1_%WDate%_sec.evt
@echo * Перемещение завершено. Имя архивного файла 'f:Logi_ForReports%1_%WDate%_sec.evtx'
@echo * Создание sql-запроса...
cscript "F:Computercreate_SQL_full7.vbs" %1 1 //nologo
@echo * Создание завершено.
@echo * Выполнение sql-запроса...
SQLCMD.EXE -S SQL-SRVSEC -d quickly -E -i f:Computer%1-1.sql -o "f:Computer%1. Запуск программ.csv" -W -R -s ";" -w 4000
@echo * Выполнение завершено.
@echo * Исправляю результирующие файлы отчетов...
cscript F:Computerupdate_result_file7.vbs "f:Computer%1. Запуск программ.csv" //nologo
@echo * Исправление завершено.
@echo * Удаление временных файлов...
del f:Logs%1.evtx
del f:Computer%1-1.sql
del "f:Computer%1. Запуск программ.csv"
@echo * Удаление временных файлов завершено.
@echo * Перемещение файлов-отчетов...
move "f:Computer%1. Запуск программ.xls" "f:CheckComps%1. Запуск программ.xls"
@echo * Перемещение завершено.
@echo on
Примечание
Возможно, в батнике нужно будет SQLCMD.EXE заменить на «c:Program FilesMicrosoft SQL Server100ToolsBinnSQLCMD.EXE», а LogParser.exe на «c:Program Files (x86)Log Parser 2.2LogParser.exe» (или «c:Program FilesLog Parser 2.2LogParser.exe»).
Имя сервера с SQL Server’ом SQL-SRV, имя экземпляра SEC и имя базы quickly. Заменить на свои.
SELECT RecordNumber as id,
eventid as eId,
TimeGenerated as Tg,
--resolve_sid(sid) as UserName,
EXTRACT_TOKEN(Strings, 1, '|') as UserName,
computername as Computer,
EXTRACT_TOKEN(Strings, 4, '|') as image_id,
EXTRACT_TOKEN(Strings, 5, '|') as image,
EXTRACT_TOKEN(Strings, 6, '|') as name
into %output_file%
FROM %source%
where (EventID in (4688;4689)) and (
(TO_UPPERCASE(resolve_sid(sid)) <> 'NT AUTHORITYNETWORK SERVICE')
and (TO_UPPERCASE(resolve_sid(sid)) <> 'NT AUTHORITYSYSTEM'))
and TimeGenerated >= TO_TIMESTAMP('01.01.2013 00:00:00','dd.MM.yyyy hh:mm:ss')
order by recordnumber desc
'on error resume next
if Wscript.Arguments.Count = 1 then
gsComputerName = Wscript.Arguments(0)
gsSQLtype = "1"
elseif Wscript.Arguments.Count = 2 then
gsComputerName = Wscript.Arguments(0)
gsSQLtype = Wscript.Arguments(1)
else
gsComputerName = InputBox("Имя компьютера", "Введите", "")
gsSQLtype = InputBox("Тип sql-запроса?" & VBNewline & "[1 - короткий, 2 - полный, 3 - оба]", "Введите", "1")
end if
set objFSO = CreateObject("Scripting.FileSystemObject")
if gsSQLtype = "1" then
fuCreateSQLFile gsComputerName, "1"
elseif gsSQLtype = "2" then
fuCreateSQLFile gsComputerName, "2"
elseif gsSQLtype = "3" then
fuCreateSQLFile gsComputerName, "1"
fuCreateSQLFile gsComputerName, "2"
end if
function fuGetTableName(lsCompName)
lsTmp = lsCompName
if InStr(lsTmp, "-") then
lsTmp = Replace(lsTmp, "-", "_")
end if
fuGetTableName = lsTmp
end function
sub fuCreateSQLFile(lsComputerName, lsSQLtype)
if lsSQLtype = "1" then
lsTemplateFilename = "f:Computertemplate-short7.sql"
elseif gsSQLtype = "2" then
lsTemplateFilename = "f:Computertemplate-full7.sql"
end if
lsLogFilename = "f:Computer" & lsComputerName & "-" & lsSQLtype & ".sql"
lsTableName = fuGetTableName(lsComputerName)
'WScript.Echo "* Имя компьютера " & lsComputerName
'WScript.Echo "* Имя таблицы " & lsTableName
'WScript.Echo "* Имя файла sql-запроса " & lsLogFilename
if not objFSO.FileExists(lsLogFilename) then
set objTextFileWriteLog = objFSO.OpenTextFile(lsLogFilename, 8, True)
else
set objTextFileWriteLog = objFSO.OpenTextFile(lsLogFilename, 2, True)
end if
Set objTextFileOpen = objFSO.OpenTextFile(lsTemplateFilename, 1)
do until objTextFileOpen.AtEndOfStream
record = objTextFileOpen.Readline
if InStr(record, "WARNING__TABLE_NAME_FOR_CHANGE") then
record = Replace(record, "WARNING__TABLE_NAME_FOR_CHANGE", lsTablename)
end if
objTextFileWriteLog.writeLine record
loop
objTextFileOpen.Close
objTextFileWriteLog.Close
end sub
SELECT TOP (100) PERCENT Computer AS [Имя компьютера], UserName AS [Учетная запись], program AS Программа, start_time AS [Время запуска],
stop_time AS [Время завершения], dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) / 3600))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 / 60))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 % 60)) AS Длительность
FROM (SELECT r.Computer, s.UserName, r.programID, r.id AS R_ID, MIN(s.id) AS S_ID, r.program, r.Tg AS start_time, MIN(s.Tg) AS stop_time
FROM (SELECT id, eId, Tg, UserName, Computer, image_id AS programID, image AS program
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 4688)
AND (Tg > CONVERT(DATETIME, '2013-01-01 00:00:00.000', 102))
AND image not like '%.scr') AS r
INNER JOIN
(SELECT id, eId, Tg, UserName, Computer, image AS programID, name AS program
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 4689)
AND name not like '%.scr') AS s
ON r.programID = s.programID AND r.program = s.program AND r.UserName = s.UserName AND r.id <= s.id
GROUP BY r.Computer, s.UserName, r.programID, r.id, r.program, r.Tg) AS DERIVEDTBL
UNION ALL
SELECT TOP (100) PERCENT Computer AS [Имя компьютера], UserName AS [Учетная запись], program AS Программа, start_time AS [Время запуска],
stop_time AS [Время завершения], dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) / 3600))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 / 60))
+ ':' + dbo.FU_GET_FULL_QTY_TEST(CONVERT(VARCHAR, DATEDIFF(SECOND, start_time, stop_time) % 3600 % 60)) AS Длительность
FROM (SELECT r.Computer, s.UserName, r.programID, r.id AS R_ID, MIN(s.id) AS S_ID, r.program, r.Tg AS start_time, MIN(s.Tg) AS stop_time
FROM (SELECT id, eId, Tg, UserName, Computer, image_id AS programID, image AS program
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 4688)
AND (Tg > CONVERT(DATETIME, '2013-01-01 00:00:00.000', 102))
AND image like '%.scr') AS r
INNER JOIN
(SELECT id, eId, Tg, UserName, Computer, image AS programID, name AS program
FROM dbo.WARNING__TABLE_NAME_FOR_CHANGE
WHERE (eId = 4689)
AND name like '%.scr') AS s
ON r.programID = s.programID AND r.program = s.program AND r.id <= s.id
GROUP BY r.Computer, s.UserName, r.programID, r.id, r.program, r.Tg) AS DERIVEDTBL2
ORDER BY 'Время запуска' DESC
'on error resume next
if Wscript.Arguments.Count = 1 then
gsFileName = Wscript.Arguments(0)
gsFileNameRes = fuRemoveExtention(gsFileName) & ".xls"
elseif Wscript.Arguments.Count = 2 then
gsFileName = Wscript.Arguments(0)
gsFileNameRes = Wscript.Arguments(1)
else
gsFileName = InputBox("Файл для обновления", "Ввод", "")
gsFileNameRes = InputBox("Файл результата", "Ввод", fuRemoveExtention(gsFileName) & ".xls")
end if
sgSimbolSplit = ";"
gsSimbolSplitFields = vbTab
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFileOpen = objFSO.OpenTextFile(gsFileName, 1)
if not objFSO.FileExists(gsFileName) then
wscript.echo "Исходного файла для обновления нет, выхожу!"
objTextFileOpen.Close
Wscript.Quit
end if
if not objFSO.FileExists(gsFileNameRes) then
set objTextFileWriteRes = objFSO.OpenTextFile(gsFileNameRes, 8, True)
else
set objTextFileWriteRes = objFSO.CreateTextFile(gsFileNameRes, True)
end if
do until objTextFileOpen.AtEndOfStream
record = objTextFileOpen.Readline
if ((InStr(record, "--------")) or (Len(record) = 0) or (InStr(record, "обработано строк")) or (InStr(record, "rows affected"))) then
'wscript.echo "пропускаю строку: '" & record & "'"
else
if InStr(record, sgSimbolSplit) then
recordRes = Replace(record, sgSimbolSplit, gsSimbolSplitFields)
else
recordRes = record
end if
objTextFileWriteRes.writeLine recordRes
end if
loop
objTextFileWriteRes.Close
objTextFileOpen.Close
WScript.Echo "Обновление завершено! Результирующий файл " & gsFileNameRes
function fuRemoveExtention(lsFilename)
lRes = lsFilename
if InStr(lsFilename, ".") then
lRes = Left(lsFilename, Len(lsFilename)-4)
end if
fuRemoveExtention = lRes
end function
На SQL Server’е надо создать функцию FU_GET_FULL_QTY_TEST:
USE [quickly]
GO
/****** Object: UserDefinedFunction [dbo].[FU_GET_FULL_QTY_TEST] Script Date: 12/03/2013 13:03:43 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[FU_GET_FULL_QTY_TEST] (@short_qty varchar(255))
RETURNS varchar(255)
AS
BEGIN
DECLARE @retMsg varchar(255)
set @retMsg = @short_qty
if len(@short_qty) <= 1
set @retMsg = '0' + @retMsg
RETURN (@retMsg)
END
Архив со скриптами можно скачать тут.
Знаю, кажется много батников и скриптов. Но достаточно один раз настроить и пользоваться потом.
И кто как делает отчёт по запуску программ на компьютерах пользователей? Поделитесь.
Автор: luzhin_kirill