Отчёт по событиям на Windows серверах домена

от автора

Всем привет!
Удобно получать в почту ежедневный отчёт о событиях на серверах домена за предыдущий день. Можно и за текущий, не суть важно. Когда такие отчёты собираются за длительный промежуток времени (за несколько лет, например), можно найти, кто завёл определённого пользователя, кто пользователя добавил/удалил из группы, кто поменял пользователю пароль (или когда он сам себе поменял), логины на серверы, неудачные логины и так далее. В принципе, каждый сам для себя определяет набор событий для отчётов. Главное принцип.
Нам, например, в почту приходит вот такой отчёт:

Кому нужно, под катом реализация.

Скрипт выполняется каждое утро в 4 часа. Для его работы на сервере надо установить LogParser и 7-ZIP (если файл отчёта больше 3 МБ, то он пакуется zip’ом).
На всякий случай ссылка на полезный документ по событиям 7-ки и 2008 сервера Vista_2008_Security_Event_Descriptions.xlsx.
У меня скрипт лежит на диске C в папке script. В папке script папка Tamplates для шаблонов. Плюс папки на F Logi_ForADReports для временных evt-файлов и Reports для html-файлов отчётов. В папке Reports также создаётся журнал работы скрипта.

Bat-файл запуска скрипта

net use Q: \\nas-srv\BACKUP cscript //nologo "c:\script\LogParser_bat_4.vbs" %1 %2 %3 net use Q: /delete 

Скрипт LogParser_bat_4.vbs

' Ежедневный отчет по событиям на серверах ' Автор Лужин Кирилл ' luzhin.kirill@yandex.ru  'On Error Resume Next  const gsReportFolder = "F:\Reports\" const gsFrom = "admin1@domain.com" const gsSubject = "send report" const gsHelpFile = "c:\script\LogParser_bat.txt" const gbDebugModeON = false  Dim oLogQuery Dim oMyInputFormat Dim oCSVOutputFormat  Dim strQuery Dim giErrorCode Dim gsFileNameLog Dim gsNormalDate Dim gsTo Dim gArrNumberOfFunctions gArrNumberOfFunctions = Array ("1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1")   gsTo = "admin1@domain.com" gsEMail = "n" ' Это для отчета за сегодня (на всякий случай): ' gsNormalDate = fuNormalizeSystemDate(cStr(Date)) ' Это для отчета за вчера (нормальный режим): gsNormalDate = fuNormalizeSystemDate(cStr(DateAdd("d", -1, Date))) gsDate = gsNormalDate gsNumberOfFunctions = "all"   gsCheckDate = DateAdd("d", -1, Date) gsLogFilename = fuGetFilename(gsCheckDate)   Set objFSO = CreateObject("Scripting.FileSystemObject") gsFileNameLog = gsReportFolder & gsNormalDate & ".log" Set objTextFileWriteLog = objFSO.OpenTextFile(gsFileNameLog, 8, True)   ' отчет за последние 33 часа: fuWritedown "* Дата отчета: " & Now, 4 gsPastDate = DateAdd("h", -33, Now)  fuWritedown "* Отчеты создаются начиная с " & gsPastDate, 4 ' отчет за последние 2 дня: ' gsPastDate = DateAdd("d", -2, Date) 	 if Wscript.Arguments.Count >= 1 then 	if lCase(Wscript.Arguments(0)) = "nothing" then 		gArrNumberOfFunctions = Array ("0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0") 		gsNumberOfFunctions = "nothing" 	elseif InStr(Wscript.Arguments(0), ",") then 		gArrNumberOfFunctions = split(Wscript.Arguments(0), ",") 		gsNumberOfFunctions = "different" 	elseif fuNeedHelp(lCase(Wscript.Arguments(0))) then 		fuTypeTextfile(gsHelpFile) 		WScript.Quit 0 	'else gArrNumberOfFunctions = Array ("1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1") 	end if 	 	if Wscript.Arguments.Count >= 2 then 		if InStr(Wscript.Arguments(1), "@") then 			gsEMail = "y" 			gsTo = Wscript.Arguments(1) 		else 			gsEMail = lCase(Wscript.Arguments(1)) 		end if 		 		if Wscript.Arguments.Count = 3 then 			gsDate = Wscript.Arguments(2) 		end if 	end if end if   fuWritedown "* Имя файла журнала: " & gsFileNameLog, 2  gStartTime = fuStartTimer("")  if gsNumberOfFunctions <> "nothing" then 	gArrProcNamesList = Array (_ 		"Процедура поиска логинов администраторов", _ 		"Процедура AccauntManage", _ 		"Процедура создания статистики неудачных логинов", _ 		"Процедура управления группами", _ 		"Процедура поиска неудачных логинов", _ 		"Процедура управления паролями", _ 		"Процедура управления компьютерами", _ 		"Процедура аудита", _ 		"Процедура статистики аудита", _ 		"Процедура поиска логинов к RDP",_ 		"Процедура слежения за действиями над объектами в AD") 		 	gArrReportfilesList = Array (_ 		gsReportFolder & "logged_Administrator_" & gsNormalDate & ".html", _ 		gsReportFolder & "new_AD_" & gsNormalDate & ".html", _ 		gsReportFolder & "logonFailuresStats_" & gsNormalDate & ".html", _ 		gsReportFolder & "group_Manage_" & gsNormalDate & ".html", _ 		gsReportFolder & "logonFailure_" & gsNormalDate & ".html", _ 		gsReportFolder & "change_password_" & gsNormalDate & ".html", _ 		gsReportFolder & "new_Comp_AD_" & gsNormalDate & ".html", _ 		gsReportFolder & "audit_" & gsNormalDate & ".html", _ 		gsReportFolder & "auditStat_" & gsNormalDate & ".html", _ 		gsReportFolder & "logged_Rdp_" & gsNormalDate & ".html", _ 		gsReportFolder & "AD_objects_" & gsNormalDate & ".html") 		   	for gix = 0 to UBound(gArrNumberOfFunctions) 		gsFunctionName = gArrProcNamesList(gix) 		gsReportfile = gArrReportfilesList(gix) 		 		if gArrNumberOfFunctions(gix) = "1" then	 			startTime = fuStartTimer(gsFunctionName) 			gArrServerList = Array ("DC1", "DC2") 			Select Case gix 				Case 0: giErrorCode = fuLogonAdministrator(gArrServerList, gsReportfile) 				Case 1: giErrorCode = fuAccauntManage(gArrServerList, gsReportfile) 				Case 2: giErrorCode = fuLogonFailureStats(gArrServerList, gsReportfile) 				Case 3: gArrServerList = Array ("DC1","DC2","EXCH1","EXCH2") 						giErrorCode = fuGroupManage(gArrServerList, gsReportfile) 				Case 4: giErrorCode = fuLogonFailures(gArrServerList, gsReportfile) 				Case 5: giErrorCode = fuPasswordManage(gArrServerList, gsReportfile) 				Case 6: giErrorCode = fuCompManage(gArrServerList, gsReportfile) 				Case 7: gArrServerList = Array ("FILE-SRV1","FILE-SRV2") 						giErrorCode = fuAudit(gArrServerList, gsReportfile) 				Case 8: gArrServerList = Array ("FILE-SRV1","FILE-SRV2") 						giErrorCode = fuAuditStat(gArrServerList, gsReportfile) 				Case 9: gArrServerList = Array ("DC1","DC2","EXCH1","EXCH2") 						giErrorCode = fuLogonRdp(gArrServerList, gsReportfile, gsFunctionName) 				Case 10: giErrorCode = fuADObjects(gArrServerList, gsReportfile) 				Case else fuWritedown "* Некорректный индекс: " & gix, 4 			End Select 			fuCheckErrorCode giErrorCode, gArrServerList, gsReportfile, gsFunctionName, startTime 		else 			fuWritedown gsFunctionName & " пропущена", 4 		end if 	next else 	fuWritedown "* Выбран вариант без создания отчетов", 4 end if  fuStopTimer(gStartTime)  if gsEMail = "y" then 	fuSendReportMail gsReportFolder & "*_" & gsDate & ".*", gsFrom, gsTo, gsSubject, gsDate else 	fuWritedown "* Выбран вариант без отсылания отчетов", 4 end if  fuWritedown "* Журнал сохранен в Файл '" & gsFileNameLog & "'", 1 fuDeleteEvtxFiles "F:\Logi_ForADReports\*.evtx" 'MsgBox "Журнал сохранен в Файл '" & gsFileNameLog & "'", vbInformation, "Информация" objTextFileWriteLog.Close  ' Процедура поиска логинов администраторов function fuLogonAdministrator(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		' Create Input Format object 		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		' Create Output Format object 		' Set oCSVOutputFormat = CreateObject("MSUtil.LogQuery.CSVOutputFormat") 		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		'oCSVOutputFormat.tabs = TRUE 		oTPLOutputFormat.tpl = "c:\script\Tamplates\logonAdministrator.tpl"  		' Создание текста запроса 		strQuery = "SELECT TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) as UserName, eventid, TimeGenerated, ComputerName as DC, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) AS LogonName, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,6,'|')) AS Domain, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,13,'|')) AS LogonWKS, " & _ 			"extract_token(trim(extract_token(Message, 18, ':' )), 0, ' ') as LogonIP, " & _ 			"CASE TO_INT(EXTRACT_TOKEN(Strings,10,'|')) " & _ 			"	WHEN 2 THEN  'Interactive - Intended for users who will be interactively using the machine, such as a user being logged on by a terminal server, remote shell, or similar process.'" & _ 			"	WHEN 3 THEN  'Network - Intended for high performance servers to authenticate clear text passwords. LogonUser does not cache credentials for this logon type.'" & _ 			"	WHEN 4 THEN  'Batch - Intended for batch servers, where processes may be executing on behalf of a user without their direct intervention; or for higher performance servers that process many clear-text authentication attempts at a time, such as mail or web servers. LogonUser does not cache credentials for this logon type.'" & _ 			"	WHEN 5 THEN  'Service - Indicates a service-type logon. The account provided must have the service privilege enabled.'" & _ 			"	WHEN 6 THEN  'Proxy - Indicates a proxy-type logon.'" & _ 			"	WHEN 7 THEN  'Unlock - This logon type is intended for GINA DLLs logging on users who will be interactively using the machine. This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.'" & _ 			"	WHEN 8 THEN  'NetworkCleartext - Windows 2000; Windows XP and Windows Server 2003 family:  Preserves the name and password in the authentication packages, allowing the server to make connections to other network servers while impersonating the client. This allows a server to accept clear text credentials from a client, call LogonUser, verify that the user can access the system across the network, and still communicate with other servers.'" & _ 			"	WHEN 9 THEN  'NewCredentials - Windows 2000; Windows XP and Windows Server 2003 family:  Allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identity, but uses different credentials for other network connections.'" & _ 			"	WHEN 10 THEN 'RemoteInteractive - Terminal Server session that is both remote and interactive.'" & _ 			"	WHEN 11 THEN 'CachedInteractive - Attempt cached credentials without accessing the network.'" & _ 			"	WHEN 12 THEN 'CachedRemoteInteractive - Same as RemoteInteractive. This is used for internal auditing.'" & _ 			"	WHEN 13 THEN 'CachedUnlock - Workstation logon'" & _ 			"	ELSE EXTRACT_TOKEN(Strings,10,'|') " & _ 			"END AS LogonType, " & _ 			"extract_token(strings, 4, '|' ) as LogonProc, " & _ 			"extract_token(strings, 11, '|' ) as ProcessID " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4624;4636) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"AND ((TO_LOWERCASE(LogonName) = TO_LOWERCASE('administrator')) " & _ 			" OR  (TO_LOWERCASE(LogonName) = TO_LOWERCASE('администратор')) " & _ 			" OR  (TO_LOWERCASE(LogonName) = TO_LOWERCASE('admin'))) " 		 		fuWritedown "* Запрос поиска логинов администраторов: '" & strQuery & "'", 4  		' Execute query 		oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		liErrorCode = 0 	else 		liErrorCode = 1 	end if  	fuLogonAdministrator = liErrorCode end function  'Процедура AccauntManage function fuAccauntManage(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false) 	'lsFROM = "\\DC1\c$\WINDOWS\system32\winevt\Logs\Archive-Security-2010-08-03-09-34-11-527.evtx" 	'lsFROM = "\\DC1\security"  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\accauntManage.tpl" 			 		strQuery = "select extract_token(extract_token(Message, 3, ':' ), 0, ' Account ') as UserName, TimeGenerated, SourceName, Message as EventCategoryName, " & _ 			"extract_token(extract_token(Message, 0, ':' ),0,'.') as Description, EventID, ComputerName, " & _ 			"extract_token(extract_token(Message, 8, ':' ), 1, ' ') as Name " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4720;4722;4725;4726;4738;4740;4767;4780;4781;4782) " &_ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss')"  		fuWritedown "* Запрос AccauntManage: '" & strQuery & "'", 4 		 		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if  	fuAccauntManage = liErrorCode end function  'Процедура создания статистики неудачных логинов function fuLogonFailureStats(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\logonFailuresStats.tpl"  		strQuery = "SELECT TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) AS User, " & _ 		"COUNT(*) AS Total " & _ 		"INTO " & lsReport & " " & _ 		"FROM " & lsFROM & " " & _ 		"WHERE EventID IN (4625) " & _ 		"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 		"GROUP BY User " & _ 		"ORDER BY Total DESC" 			 		fuWritedown "* Запрос статистики неудачных логинов: '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuLogonFailureStats = liErrorCode end function  'Процедура управления группами function fuGroupManage(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\groupManage.tpl"  		strQuery = "SELECT extract_token(extract_token(Message, 3, ':' ), 0, ' Account ') as UserName, TimeGenerated, SourceName, EventCategoryName, " & _  			"extract_token(extract_token(Message, 0, ':' ), 0, '.') as EventIDName, " & _ 			"COALESCE(extract_token(extract_token(strings, 0, ',' ), 1, '='), extract_token(strings, 0, '|' ), strings) as Name, " & _ 			"COALESCE(extract_token(extract_token(strings, 0, ',' ), 1, '='), extract_token(strings, 1, '|' ), strings) as SIDName, " & _ 			"extract_token(strings, 2, '|' ) as Name_Group, " & _ 			"EventID, extract_token(ComputerName, 0, '.') " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4727;4728;4729;4730;4731;4732;4733;4734;4735;4737;4744;4745;4746;4747;4748;4749;4750;4751;4752;4753;4754;4755;4756;4757;4758;4759;4760;4761;4762;4764;4783;4784;4785;4786;4787;4788;4789;4790) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss')" 			 		fuWritedown "* Запрос управления группами: '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuGroupManage = liErrorCode end function  'Процедура поиска неудачных логинов function fuLogonFailures(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\logonFailures.tpl"  		strQuery = "SELECT COUNT(EventID) AS TotalLogonFailures, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,5,'|')) AS User, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,6,'|')) AS Domain, " & _ 			"TO_LOWERCASE(EXTRACT_TOKEN(Strings,13,'|')) AS WorkStation, " & _ 			"CASE TO_INT(EXTRACT_TOKEN(Strings,10,'|')) " & _ 			"	WHEN 2 THEN  'Interactive - Intended for users who will be interactively using the machine, such as a user being logged on by a terminal server, remote shell, or similar process.'" & _ 			"	WHEN 3 THEN  'Network - Intended for high performance servers to authenticate clear text passwords. LogonUser does not cache credentials for this logon type.'" & _ 			"	WHEN 4 THEN  'Batch - Intended for batch servers, where processes may be executing on behalf of a user without their direct intervention; or for higher performance servers that process many clear-text authentication attempts at a time, such as mail or web servers. LogonUser does not cache credentials for this logon type.'" & _ 			"	WHEN 5 THEN  'Service - Indicates a service-type logon. The account provided must have the service privilege enabled.'" & _ 			"	WHEN 6 THEN  'Proxy - Indicates a proxy-type logon.'" & _ 			"	WHEN 7 THEN  'Unlock - This logon type is intended for GINA DLLs logging on users who will be interactively using the machine. This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.'" & _ 			"	WHEN 8 THEN  'NetworkCleartext - Windows 2000; Windows XP and Windows Server 2003 family:  Preserves the name and password in the authentication packages, allowing the server to make connections to other network servers while impersonating the client. This allows a server to accept clear text credentials from a client, call LogonUser, verify that the user can access the system across the network, and still communicate with other servers.'" & _ 			"	WHEN 9 THEN  'NewCredentials - Windows 2000; Windows XP and Windows Server 2003 family:  Allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identity, but uses different credentials for other network connections.'" & _ 			"	WHEN 10 THEN 'RemoteInteractive - Terminal Server session that is both remote and interactive.'" & _ 			"	WHEN 11 THEN 'CachedInteractive - Attempt cached credentials without accessing the network.'" & _ 			"	WHEN 12 THEN 'CachedRemoteInteractive - Same as RemoteInteractive. This is used for internal auditing.'" & _ 			"	WHEN 13 THEN 'CachedUnlock - Workstation logon'" & _ 			"	ELSE EXTRACT_TOKEN(Strings,10,'|') " & _ 			"END AS Type " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4625) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"GROUP BY User,Domain,WorkStation,Type " & _ 			"ORDER BY TotalLogonFailures DESC" 			 		fuWritedown "* Запрос создания статистики неудачных логинов: '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuLogonFailures = liErrorCode end function  'Процедура управления паролями function fuPasswordManage(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\PasswordManage.tpl" 		 		strQuery = "SELECT extract_token(extract_token(Message, 3, ':' ), 0, ' Account ') as UserName, TimeGenerated, SourceName, EventCategoryName, " & _ 			"extract_token(extract_token(Message, 0, ':' ),0,'.') as Description, EventID, ComputerName, " & _ 			"extract_token(extract_token(Message, 8, ':' ), 0, ' Account ') as Name " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4723;4724;4782;4793) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss')" 			 		fuWritedown "* Запрос управления паролями: '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuPasswordManage = liErrorCode end function  'Процедура управления компьютерами function fuCompManage(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\compManage.tpl" 		 		strQuery = "SELECT extract_token(extract_token(Message, 3, ':' ), 0, ' Account ') as UserName, TimeGenerated, SourceName, EventCategoryName, " & _ 			"extract_token(extract_token(Message, 0, ':' ),0,'.') as Description, EventID, ComputerName, " & _ 			"extract_token(extract_token(Message, 8, ':' ), 0, ' Account ') as Name " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID in (4720;4742;4743) " & _ 			"and Name like '%%$%%' " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss')" 			 		fuWritedown "* Запрос управления компьютерами: '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuCompManage = liErrorCode end function  'Процедура аудита function fuAudit(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\audit.tpl"  		strQuery = "select TimeGenerated, EventID, " & _ 			"extract_token(Strings, 0, '|' ) as UserSID,  " & _ 			"extract_token(Strings, 6, '|' ) as ObjectName, " & _ 			"extract_token(Strings, 1, '|' ) as User, " & _ 			"extract_token(Strings, 2, '|' ) as Domain, " & _ 			"extract_token(Strings, 5, '|' ) as ObjectType, " & _ 			"extract_token(Strings, 11, '|' ) as ProgramName, " & _ 			"extract_token(Message, 0, '.' ) as Event " & _ 			"into " & lsReport & " " & _ 			"from " & lsFROM & " " & _ 			"where EventId in (4656;4659;4660;4661;4663;4691) " & _ 			"and TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"and User <> 'NT AUTHORITY\SYSTEM' " & _ 			"and extract_token(Strings, 6, '|' ) not like '%%HarddiskVolumeShadowCopy%%' " & _ 			"and extract_token(Strings, 6, '|' ) not like '%%ShadowCopyVolume%%' " & _ 			"and TO_LOWERCASE(extract_token(Strings, 6, '|' )) like '%%Top-Secret-Documents%%' " & _ 			"and User <> 'FILE-SRV1$' " & _ 			"and User <> 'FILE-SRV2$' " & _ 			"order by Timegenerated" 			 		fuWritedown "* Запрос " & lsFunctionName & ": '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		lsFROM = fuCollectFileList(lArrServerList, true) 		 		if lsFROM <> "" then 			Set oLogQuery = CreateObject("MSUtil.LogQuery")  			Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 			oEVTInputFormat.direction = "BW"  			Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 			oTPLOutputFormat.tpl = "c:\script\Tamplates\audit.tpl"  			strQuery = "select TimeGenerated, EventID, " & _ 				"extract_token(Strings, 0, '|' ) as UserSID,  " & _ 				"extract_token(Strings, 6, '|' ) as ObjectName, " & _ 				"extract_token(Strings, 1, '|' ) as User, " & _ 				"extract_token(Strings, 2, '|' ) as Domain, " & _ 				"extract_token(Strings, 5, '|' ) as ObjectType, " & _ 				"extract_token(Strings, 11, '|' ) as ProgramName, " & _ 				"extract_token(Message, 0, '.' ) as Event " & _ 				"into " & lsReport & " " & _ 				"from " & lsFROM & " " & _ 				"where EventId in (4656;4659;4660;4661;4663;4691) " & _ 				"and TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 				"and User <> 'NT AUTHORITY\SYSTEM' " & _ 				"and extract_token(Strings, 6, '|' ) not like '%%HarddiskVolumeShadowCopy%%' " & _ 				"and extract_token(Strings, 6, '|' ) not like '%%ShadowCopyVolume%%' " & _ 				"and TO_LOWERCASE(extract_token(Strings, 6, '|' )) like '%%Top-Secret-Documents%%' " & _ 				"and User <> 'FILE-SRV1$' " & _ 				"and User <> 'FILE-SRV2$' " & _ 				"order by Timegenerated" 				 			fuWritedown "* Запрос " & lsFunctionName & ": '" & strQuery & "'", 4  			if not gbDebugModeON then 				oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  			end if 		else 			fuWritedown "* Что-то с аудитом совсем плохо.", 4 		end if 		 		liErrorCode = 1 	end if 	 	fuAudit = liErrorCode end function  'Процедура статистики аудита function fuAuditStat(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\auditStat.tpl"  		strQuery = "select extract_token(Strings, 1, '|' ) as User, " & _ 			"COUNT(*) as Qty, " & _ 			"MAX(TimeGenerated) as MaxTime  " & _ 			"into " & lsReport & " " & _ 			"from " & lsFROM & " " & _ 			"where EventId in (4656;4659;4660;4661;4663;4691) " & _ 			"and TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"and User <> 'NT AUTHORITY\SYSTEM' " & _ 			"and extract_token(Strings, 6, '|' ) not like '%%HarddiskVolumeShadowCopy%%' " & _ 			"and extract_token(Strings, 6, '|' ) not like '%%ShadowCopyVolume%%' " & _ 			"and TO_LOWERCASE(extract_token(Strings, 6, '|' )) like '%%Top-Secret-Documents%%' " & _ 			"group by User " & _ 			"order by User" 		 		fuWritedown "* Запрос " & lsFunctionName & ": '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		lsFROM = fuCollectFileList(lArrServerList, true) 		 		if lsFROM <> "" then 			Set oLogQuery = CreateObject("MSUtil.LogQuery")  			Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 			oEVTInputFormat.direction = "BW"  			Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 			oTPLOutputFormat.tpl = "c:\script\Tamplates\auditStat.tpl"  			strQuery = "select extract_token(Strings, 1, '|' ) as User, " & _ 				"COUNT(*) as Qty, " & _ 				"MAX(TimeGenerated) as MaxTime  " & _ 				"into " & lsReport & " " & _ 				"from " & lsFROM & " " & _ 				"where EventId in (4656;4659;4660;4661;4663;4691) " & _ 				"and TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 				"and User <> 'NT AUTHORITY\SYSTEM' " & _ 				"and extract_token(Strings, 6, '|' ) not like '%%HarddiskVolumeShadowCopy%%' " & _ 				"and extract_token(Strings, 6, '|' ) not like '%%ShadowCopyVolume%%' " & _ 				"and TO_LOWERCASE(extract_token(Strings, 6, '|' )) like '%%Top-Secret-Documents%%' " & _ 				"group by User " & _ 				"order by User" 			 			fuWritedown "* Запрос " & lsFunctionName & ": '" & strQuery & "'", 4  			if not gbDebugModeON then 				oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  			end if 		else 			fuWritedown "* Что-то со статистикой аудитом совсем плохо.", 4 		end if 	 		liErrorCode = 1 	end if 	 	fuAuditStat = liErrorCode end function  'Процедура поиска логинов к RDP function fuLogonRdp(lArrServerList, lsReport, lsFunctionName) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false)  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\logonRdp.tpl"  		strQuery = "SELECT DISTINCT resolve_sid(SID) as UserName, eventid, TimeGenerated, extract_token(ComputerName, 0, '.') as NormComputerName, " & _ 			"extract_token(strings, 5, '|' ) as LogonName, " & _ 			"extract_token(strings, 13, '|' ) as LogonWKS, " & _ 			"extract_token(strings, 18, '|' ) as LogonIP, " & _ 			"case extract_token(strings, 8, '|' ) " & _ 			" WHEN '2' THEN 'interactive' " & _ 			" WHEN '3' THEN 'network' " & _ 			" WHEN '4' THEN 'batch' " & _ 			" WHEN '5' THEN 'service' " & _ 			" WHEN '7' THEN 'unlocked workstation' " & _ 			" WHEN '8' THEN 'network logon using a cleartext password' " & _ 			" WHEN '9' THEN 'impersonated logons' " & _ 			" WHEN '10' THEN 'remote access' " & _ 			" ELSE extract_token(strings, 8, '|' ) " & _ 			"end as LogonType, " & _ 			"extract_token(strings, 17, '|' ) as LogonProc, " & _ 			"extract_token(strings, 16, '|' ) as ProcessID " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4624;4625;4648;4675) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"AND LogonType = 'remote access' " & _ 			"order by Timegenerated DESC" 			 		fuWritedown "* Запрос " & lsFunctionName & ": '" & strQuery & "'", 4  		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuLogonRdp = liErrorCode end function  function fuADObjects(lArrServerList, lsReport) 	liErrorCode = -1 	lsFROM = fuCollectFileList(lArrServerList, false) 	'lsFROM = "\\DC1\c$\WINDOWS\system32\winevt\Logs\Archive-Security-2010-12-09-09-55-23-631.evtx" 	'lsFROM = "\\DC1\security"  	if lsFROM <> "" then 		Set oLogQuery = CreateObject("MSUtil.LogQuery")  		Set oEVTInputFormat = CreateObject("MSUtil.LogQuery.EventLogInputFormat") 		oEVTInputFormat.direction = "BW"  		Set oTPLOutputFormat = CreateObject("MSUtil.LogQuery.TemplateOutputFormat") 		oTPLOutputFormat.tpl = "c:\script\Tamplates\adobjects.tpl" 			 		strQuery = "select extract_token(extract_token(Message, 3, ':' ), 0, ' Account ') as UserName, TimeGenerated, SourceName, Message as EventCategoryName, " & _ 			"extract_token(extract_token(Message, 0, ':' ),0,'.') as Description, EventID, ComputerName, " & _ 			"extract_token(extract_token(Message, 8, ':' ), 1, ' ') as Name " & _ 			"INTO " & lsReport & " " & _ 			"FROM " & lsFROM & " " & _ 			"WHERE EventID IN (4928;4929;4930;4931;4934;4935;4936;4937;4662;5136;5137;" & _ 			"5138;5139;5141;4932;4933) " & _ 			"AND TimeGenerated >= TO_TIMESTAMP('" & gsPastDate & "','dd.MM.yyyy hh:mm:ss') " & _ 			"AND UserName not like '%%RTCService%%' "  		fuWritedown "* Запрос ADObjects: '" & strQuery & "'", 4 		 		if not gbDebugModeON then 			oLogQuery.ExecuteBatch strQuery, oEVTInputFormat, oTPLOutputFormat  		end if 		 		liErrorCode = 0 	else 		liErrorCode = 1 	end if 	 	fuADObjects = liErrorCode end function   ' Служебные функции function fuSendReportMail(lsFileMask, lsFrom, lsTo, lsSubject, lsDate) 	Set objEmail = CreateObject("CDO.Message") 	objEmail.From = lsFrom 	objEmail.To = lsTo 	objEmail.Subject = lsSubject 	objEmail.HTMLBody = "<span style='font-family:Tahoma,Arial,sans-serif;font-size:14pt;'>Отчёты за " & _ 		lsDate & "</span>"  	fuCheckfileSizeAndZIP lsDate 	 	Set oLogQuery = CreateObject("MSUtil.LogQuery") 	Set oFormat = CreateObject("MSUtil.LogQuery.FileSystemInputFormat") 	Set oRecordSet = oLogQuery.Execute("SELECT * FROM " & lsFileMask, oFormat)  	i = 0 	While Not oRecordSet.atEnd 	    Set oRecord = oRecordSet.getRecord() 	    strValue = oRecord.getValue("Path") 	    objEmail.AddAttachment strValue 	    i = i + 1 	    oRecordSet.moveNext 	Wend 	oRecordSet.Close  	objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 	objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver")="MAIL-SRV"  	objEmail.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 	objEmail.Configuration.Fields.Update 	objEmail.Send  	fuWritedown "* Отчеты отправлены от '" & lsFrom & "' на '" & lsTo & "'. Количество файлов-отчетов: " & i, 4 end function  function fuCheckErrorCode(liErrorCode, lArrServerList, lsReportfile, lsFunctionName, startTime) 	select case liErrorCode 		case -1:  fuWritedown "* " & lsFunctionName & " не выполнилась (функция не отработала корректно)", 4 		case 0:   fuWritedown "* " & lsFunctionName & " завершена", 4 				  fuCheckResultFile(lsReportfile) 		case 1:   fuWritedown "* Для серверов '" & Join(lArrServerList, ",") & "' не найдены архивные папки/файлы, по которым делать отчет (блок FROM пустой). Поиск выполняется по текущим журналам.", 4 				  fuCheckResultFile(lsReportfile) 		case else fuWritedown "* Непридвиденная ошибка в " & lsFunctionName & "!", 4 	end select 	 	fuStopTimer(startTime) 	fuWritedown "", 4 end function  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 			lBoo = true 		end if 	next 	 	fuPing = lBoo end function  function fuCollectFileList(lArrServerList, lbFindOnServer) 	' true для поиска в текущих журналах, false для поиска в архивных журналах: 	' lbFindOnServer = true 	' lbFindOnServer = false 	 	lsTmp = Join(lArrServerList, ",") 	fuWritedown "* Список компьютеров: " & lsTmp, 4 	lsList = "" 	lsListFiles = "" 	lsTmpPath = "" 	lbServerHaveArchive = false  	for lix = 0 to UBound(lArrServerList) 		lsServer = lArrServerList(lix) 		fuWritedown "* Компьютер '" & lsServer & "'", 4 		 		if lbFindOnServer then		 			if fuPing(lsServer) then 				fuWritedown "* Есть в сети", 4 				lsList = lsList & "\\" & lsServer & "\Security" 				 					if fuServerHaveArchive(lsServer, lsListFiles) then 						lbServerHaveArchive = true 						'lsList = lsList & "," & "\\" & lsServer & "\c$\WINDOWS\system32\config\archive-security-*.evtx" 						if len(lsListFiles) <> 0 then 							'lsList = lsList & "," & lsListFiles 						end if 					end if 				 				if lix < UBound(lArrServerList) then 					lsList = lsList & "," 				end if 			else 				fuWritedown "* Нет в сети", 4 			end if 		else 			lbServerHaveArchive = false 			 			if Len(lsListFiles) = 0 then 				lsListFiles = fuGetLogFolder(lsServer) 			else 				lsTmpPath = fuGetLogFolder(lsServer) 				if Len(lsTmpPath) <> 0 then 					lsListFiles = lsListFiles & "," & lsTmpPath 				end if 			end if 		end if 		 	next  	if Right(lsList, 2) = ", " then 		lsList = Left(lsList, Len(lsList)-2) 	end if 	 	'\\dc1\Security, \\dc1\c$\WINDOWS\system32\config\Archive-Security-*.evt,  	'\\dc2\Security, \\dc2\c$\WINDOWS\system32\config\Archive-Security-*.evt 	 	if lbServerHaveArchive then 		lsList = lsList & "," & lsListFiles 	end if 	 	if not lbFindOnServer then 		lsList = lsListFiles 	end if 	 	fuWritedown "* Блок FROM из функции: '" & lsList & "'", 4 	fuCollectFileList = lsList end function  function fuServerHaveArchive(lsServerName, lsListFiles_a) 	Const FILE_NAME = 0  	dim gbFoo 	dim gsFilename  	gbFoo = false  	Set objShell = CreateObject ("Shell.Application") 	Set objFolder = objShell.Namespace ("\\" & lsServerName & "\c$\Windows\System32\winevt\Logs")  	For Each strFileName in objFolder.Items 		gsFilename = trim(lCase(objFolder.GetDetailsOf (strFileName, FILE_NAME))) 		' fuWritedown "* gsFilename: " & gsFilename, 1 	    if ((InStr(gsFilename, "archive-security-")) and (Right(gsFilename, 4) = "evtx")) then 			fuWritedown "* Архив найден! \\" & lsServerName & "\c$\Windows\System32\winevt\Logs\"&gsFilename, 4 			if len(lsListFiles_a) = 0 then 				lsListFiles_a = "f:\Logi_ForADReports\" & gsFilename 			else  				lsListFiles_a = lsListFiles_a & "," & "f:\Logi_ForADReports\" & gsFilename 			end if 			fuWritedown "* lsListFiles_a: " & lsListFiles_a, 2 			'fuConvertEvt2Evtx "\\" & lsServerName & "\c$\WINDOWS\system32\config\" & gsFilename, gsFilename 			fuCopyEvtx "\\" & lsServerName & "\c$\Windows\System32\winevt\Logs\" & gsFilename, gsFilename 			gbFoo = true 		end if 	Next  	if gbFoo then 		fuWritedown "* На компьютере '" & lsServerName & "' архивы журналов есть", 4 	else 		fuWritedown "* На компьютере '" & lsServerName & "' архивов журналов нет", 4 	end if  	 	fuServerHaveArchive = gbFoo end function  function fuConvertEvt2Evtx(lsFilenamePath, lsFilename) 	lbTmp = true 	 	if (fuIsFileExists("f:\Logi_ForADReports\" & lsFilename) and (fuIsFileExists("f:\Logi_ForADReports\" & lsFilename & "x"))) then 		fuWritedown "* Конвертация файла " & lsFilename & " не нужна, уже есть сконвертированный", 4 	else 		fuWritedown "* Конвертируем файл " & lsFilename & "...", 4  		Set WshShell = CreateObject("WScript.Shell")  		gsRunCmd = "c:\script\convert_evt_to_evtx.bat " & lsFilenamePath & " " & lsFilename  		fuWritedown "* Выполняется команда: '" & gsRunCmd & "'", 2 		WshShell.Run gsRunCmd 		 		WScript.Sleep 300000 	end if 	 	fuConvertEvt2Evtx = lbTmp end function   function fuCopyEvtx(lsFilenamePath, lsFilename) 	lbTmp = true  	if not fuIsFileExists("f:\Logi_ForADReports\" & lsFilename) then 		Set WshShell = CreateObject("WScript.Shell") 		 		gsRunCmd = "c:\script\copy_evtx.bat " & lsFilenamePath & " " & lsFilename 		fuWritedown "* Выполняется команда: '" & gsRunCmd & "'", 4 		WshShell.Run gsRunCmd 			 		WScript.Sleep 25000 	else 		fuWritedown "* Архивный журнал " & lsFilename & " копировать не нужно, уже есть скопированный", 4 	end if 	 	fuCopyEvtx = lbTmp end function   function fuDeleteEvtxFiles(lsFromList) 	fuWritedown "* Удаление временных файлов: " & lsFromList, 4 	lbTmp = true 	 	Set WshShell = CreateObject("WScript.Shell") 	 	if InStr(lsFromList, ",") then 		lArrFrom = Split(lsFromList, ",") 		 		for lix = 0 to uBound(lArrFrom) 			if InStr(lCase(lArrFrom(lix)), "archive-security-") then 				gsRunCmd = "c:\script\del_evtx.bat " & lArrFrom(lix)  				fuWritedown "* Выполняется команда: '" & gsRunCmd & "'", 4 				WshShell.Run gsRunCmd 			end if 		next 	else 		gsRunCmd = "c:\script\del_evtx.bat " & lsFromList  		fuWritedown "* Выполняется команда: '" & gsRunCmd & "'", 4 		WshShell.Run gsRunCmd 	end if 	 	WScript.Sleep 60000 	 	fuDeleteEvtxFiles = lbTmp end function    function fuIsFileExists(lsFilename) 	lBoo = false 	 	Set FSO = CreateObject("Scripting.FileSystemObject") 	if FSO.FileExists(lsFilename) then 		' Файл существует 		lBoo = true 	else  		' Файла не существует 	end if 	Set FSO = nothing 	 	fuIsFileExists = lBoo end function  function fuWritedown(lsToWrite, liCase) 	Select Case liCase 		Case 0: ' ничего не делать. Сообщение уходит в никуда. 		Case 1: WScript.Echo lsToWrite ' сообщение только на экран 		Case 2: objTextFileWriteLog.WriteLine lsToWrite ' сообщение только в журнал 		Case 4: WScript.Echo lsToWrite ' сообщение и на экран, и в журнал 				objTextFileWriteLog.WriteLine lsToWrite 		Case else WScript.Echo lsToWrite 	End Select end function   function fuNormalizeSystemDate(lsDate) 	lsNormalizeDate = lsDate 	 	if InStr(lsDate, ".") then 		lArrDate = Split(lsDate, ".") 		lsNormalizeDate = lArrDate(2) & "." & lArrDate(1) & "." & lArrDate(0) 	elseif InStr(lsDate, "/") then 		lArrDate = Split(lsDate, "/") 		lsNormalizeDate = fuCheckDatePart(lArrDate(2)) & "." & fuCheckDatePart(lArrDate(0)) & "." & fuCheckDatePart(lArrDate(1)) 	end if 	 	fuNormalizeSystemDate = lsNormalizeDate end function   function fuNormalizeDate(lsDate) 	lsNormalizeDate = lsDate 	 	if InStr(lsDate, ".") then 		lArrDate = Split(lsDate, ".") 		lsNormalizeDate = lArrDate(2) & "." & lArrDate(1) & "." & lArrDate(0) 	end if 	 	fuNormalizeDate = lsNormalizeDate end function   function fuCheckDatePart(lsDate) 	lsNormalizeDate = lsDate 	 	if len(lsDate) <= 1 then 		lsNormalizeDate = "0" & lsDate 	end if 	 	fuCheckDatePart = lsNormalizeDate end function   function fuStartTimer(lsFunctionName) 	fuStartTimer = Now() 	if lsFunctionName <> "" then 		fuWritedown VBNewLine & lsFunctionName & " запущена", 4 	end if end function   function fuStopTimer(startTime) 	EndTime = Now() 	timeDiff = CDate(EndTime - startTime) 	fuWritedown "* Поиск выполнялся: " & timeDiff & " (" & startTime & "/" & EndTime & ").", 4 end function   function fuCheckResultFile(lsReportfile) 	if objFSO.FileExists(lsReportfile) then 		fuWritedown "* Результат сохранен в файл '" & lsReportfile & "'", 4 	else  		fuWritedown "* Файл результатов '" & lsReportfile & "' не был создан, так как поиск не дал результатов", 4 	end if end function   function fuTypeTextfile(lsTextfile) 	'fuWritedown "Распечатать файл помощи '" & lsTextfile & "'", 1 	Set objTextFileShowHelp = objFSO.OpenTextFile(lsTextfile, 1) 	Do Until objTextFileShowHelp.AtEndOfStream 		fuWritedown objTextFileShowHelp.Readline, 1 	Loop 	objTextFileShowHelp.Close end function   function fuNeedHelp(lsPar) 	lbFoo = false 	if  lsPar = "h" or lsPar = "help" or InStr(lsPar, "?") then 		lbFoo = true 	end if 	fuNeedHelp = lbFoo end function    function fuGetFilename(lsDate) 	lsTmp = "Archive-Security-2013-12-01-*.evtx" 	 	if InStr(lsDate, ".") then 		lArrDate = Split(lsDate, ".") 		lsTmp = "Archive-Security-" & fuCheckDatePart(lArrDate(2)) & "-" & fuCheckDatePart(lArrDate(1)) & "-" & fuCheckDatePart(lArrDate(0)) & "-*.evtx" 	elseif InStr(lsDate, "/") then 		lArrDate = Split(lsDate, "/") 		lsTmp = "Archive-Security-" & fuCheckDatePart(lArrDate(2)) & "-" & fuCheckDatePart(lArrDate(1)) & "-" & fuCheckDatePart(lArrDate(0)) & "-*.evtx" 	end if 	 	fuGetFilename = lsTmp end function   function fuGetLogFolder(lsServer) 	lsTmp = "" 	 	Select Case lsServer 		Case "DC1": lsTmp = "Q:\Logi_DC1\" 		Case "DC2": lsTmp = "Q:\Logi_DC2\" 		Case "FILE-SRV1": lsTmp = "Q:\Logi_FILE-SRV1\" 		Case "FILE-SRV2": lsTmp = "Q:\Logi_FILE-SRV2\" 		Case "EXCH1": lsTmp = "Q:\Logi_EXCH1\" 		Case "EXCH2": lsTmp = "Q:\Logi_EXCH2\" 		Case else  			fuWritedown "* В скрипте папка с архивами сервера " & lsServer & " не указана. Пытаюсь папку угадать 'Q:\Logi_" & lsServer & "\'", 4 			lsTmp = "Q:\Logi_" & lsServer & "\" 	End Select 	 	 	lsPath = Left(lsTmp, Len(lsTmp)-1) 	'lsPath = lsTmp 	lsFile = gsLogFilename  	lsBoo = fuNASHaveArchive(lsServer, lsPath, lsFile)  	if lsBoo then 		lsTmp = lsTmp & gsLogFilename 	else 		lsTmp = "" 	end if 	 	fuGetLogFolder = lsTmp end function    function fuNASHaveArchive(Server, Path, File) 	wscript.echo Server & ", " & Path & ", " & File  	Const FILE_NAME = 0  	dim gbFoo 	dim gsFilename  	gbFoo = false 	 	lsF = lCase(Left(File, Len(File)-6))  	Set objShell = CreateObject("Shell.Application") 	Set objFolder = objShell.Namespace(Path)  	For Each strFileName in objFolder.Items 		gsFilename = trim(lCase(objFolder.GetDetailsOf (strFileName, FILE_NAME))) 		' wscript.echo  "* gsFilename: " & gsFilename 	    if InStr(gsFilename, lsF) then 			gbFoo = true 		end if 	Next  	fuNASHaveArchive = gbFoo end function   function fuCheckfileSizeAndZIP(lsDate) 	lsReportFolder = "F:\Reports\" 	lArrReportfilesList = Array (_ 		lsReportFolder & "logged_Administrator_" & lsDate & ".html", _ 		lsReportFolder & "new_AD_" & lsDate & ".html", _ 		lsReportFolder & "logonFailuresStats_" & lsDate & ".html", _ 		lsReportFolder & "group_Manage_" & lsDate & ".html", _ 		lsReportFolder & "logonFailure_" & lsDate & ".html", _ 		lsReportFolder & "change_password_" & lsDate & ".html", _ 		lsReportFolder & "new_Comp_AD_" & lsDate & ".html", _ 		lsReportFolder & "audit_" & lsDate & ".html", _ 		lsReportFolder & "auditStat_" & lsDate & ".html", _ 		lsReportFolder & "logged_Rdp_" & lsDate & ".html", _ 		gsReportFolder & "AD_objects_" & gsNormalDate & ".html")  	for lix = 0 to UBound(lArrReportfilesList) 		lbTmp = false 		 		lsFilenamePath = lArrReportfilesList(lix) 		ArcName = Left(lsFilenamePath, Len(lsFilenamePath)-5) & ".zip" 		 		if fuIsFileExists(lsFilenamePath) then 			Set File = objFSO.GetFile(lsFilenamePath)  			 lsFilenameSize =  File.Size 			 if lsFilenameSize > 3000000 then 				fuWritedown "* Размер файла '" & lsFilenamePath & "' больше 3 МБ (размер " & lsFilenameSize & " байт), необходимо его заархивировать", 4 				fuWritedown "* Идет архивация...", 1 				'--[ Архивирование отчета ]------------------------------------------------------------------- 				Set Shell=CreateObject("WScript.Shell") 				Set Zip=Shell.Exec("C:\Program Files\7-Zip\7z.exe a " & ArcName & " " & lsFilenamePath)  				'Необходимо ожидание, пока архивирование не закончится 				While (Zip.Status = 0) 					WScript.Sleep 5000 				Wend  				Set Shell = Nothing  				fuWritedown "* Архивирование завершено! Имя архива '" & ArcName & "'", 4 				fuWritedown "* Удаляем файл отчета '" & lsFilenamePath & "'...", 4 				objFSO.DeleteFile lsFilenamePath, true 				fuWritedown "* Удаление завершено!", 1 				lbTmp = true 				'WScript.Sleep 2000 				'--------------------------------------------------------------------------------------------- 			 end if 		else  			' файла не существует, ничего не делаем. 		end if 	next 	 	fuCheckfileSizeAndZIP = lbTmp end function  

Вспомагательные батники.

convert_evt_to_evtx.bat

copy %1 f:\Logi_ForADReports\%2 wevtutil epl f:\Logi_ForADReports\%2 f:\Logi_ForADReports\%2x /lf:true 

copy_evtx.bat

copy %1 f:\Logi_ForADReports\%2 

del_evtx.bat

del %1 

Скрипт может запускаться без каких-либо ключей. В этом случае создаются все одиннадцать отчетов.
Скрипт может иметь три ключа.

Logparser_4.bat [список_отчетов] [адрес_электронной_почты] [дата] 

[список_отчетов] — необязательный ключ. Перечень отчетов, которые надо выполнить. Указывается в формате: «1,1,0,0,1,0,1,0,1,0,0», то есть единица указывает, что отчет надо выполнить.
Можно сделать все отчеты, указав ключ all.
Выключает создание всех отчетов ключ nothing.

[адрес_электронной_почты] — необязательный ключ. Может принимать значения:
y — отправить отчеты на адрес по умолчанию (admin1@domain.com)
n — не отправлять отчеты на электронный ящик, а только сложить в папку отчетов f:\Reports.
адрес_электронной_почты — Указывает адрес электронной почты, на который будут отосланы отчеты.

[дата] — необязательный ключ. Указывает дату для работы с отчетами. Этот параметр указывается только тогда, когда надо отправить уже сделанные отчеты за дату в прошлом (Отчеты всегда выполняются за предыдущий день от даты запуска скрипта). Формат даты: YYYY.MM.DD

Отчеты:
1. Отчет поиска логинов администраторов
2. Отчет AccauntManage
3. Отчет создания статистики неудачных логинов
4. Отчет управления группами
5. Отчет поиска неудачных логинов
6. Отчет управления паролями
7. Отчет управления компьютерами
8. Отчет аудита по папке Top-Secret-Documents
9. Отчет статистики аудита по папке Top-Secret-Documents
10. Отчет поиска логинов к RDP
11. Отчет слежения за действиями над объектами в AD

Примеры.

Logparser_4.bat nothing "admin2@domain.com" 2013.01.01 

Все уже сделанные отчеты за 1 января 2013 г. отсылает на «admin2@domain.com» (заново отчеты не выполняются).

Logparser_4.bat nothing y 2013.02.18 

Все уже сделанные отчеты за 18 февраля 2013 г. отсылает на адрес по умолчанию (заново отчеты не выполняются).

Logparser_4.bat all "admin3@domain.com" 

Создает все отчеты и отсылает на «admin3@domain.com».

Logparser_4.bat "1,0,0,0,0,0,0,0,0,1,0" 

Создает только первый и последний отчёты и отсылает на адрес по умолчанию.

Logparser_4.bat "0,1,0,0,0,0,0,0,0,0,0" n 

Создает только второй отчет, но никуда не отсылает, а складывет в папку f:\Reports.

Logparser_4.bat /? 

Показывает помощь.

Примечание.
Сейчас скрипт ищет события в архивных журналах безопасности (те, что Archive-Security-*.evt) в централизованном хранилище. В скрипте это диск Q, подключенный в начале в батнике

net use Q: \\nas-srv\BACKUP

Но может искать в оперативных и архивных журналах на серверах. Для этого нужно в каждой их 11 функций изменить

lsFROM = fuCollectFileList(lArrServerList, false)

на

lsFROM = fuCollectFileList(lArrServerList, true)

Тут можно скачать архив со скриптом, батниками и шаблонами.
В принципе, не обязательно использовать скрипт дословно. Главное понять принцип, как логпарсер ищет события и выгружает их в html-файл, используя шаблон. И пользоваться.

ссылка на оригинал статьи http://habrahabr.ru/post/205128/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *