Добрый день, в этой заметке пойдет речь о второй части централизованном аудите сетевых файловых ресурсах в большой организации.
Клиентская часть
Первым делом необходимо включить ведение штатного аудита объектов в локальной политике файлового сервера:
Вызываем консоль "Локальных политик" командой "gpedit.msc"
WIN+R >> вставить "gpedit.msc" >> ввод
По пути
– Computer Configuration
– Windows Settings
– Security Settings
– Local Policies
– Audio Policy
– Audit object Access
необходимо установить флаг Success.
Создаем папку с путем "C:\Scripts\"
В ней текстовый файл с именем, например audit_shared и расширением "ps1"
в него необходимо записать следующий код и сохранить
#Что бы сразу начать загружать события установим время начала загрузки событий -1 секунду с момента запуска
$Start_Time = (Get-Date).AddSeconds(-1)
#Необходимо получить версию ОС, так как на 2008 и 2012 журналы событий ведутся по #разному
$OS = (Get-WmiObject Win32_OperatingSystem).version
#Вводные переменные, сервер база и тп., последняя строчка преобразует все в правильный вид
$SQl_Server = 'prm-test-sql'
$SQLDateBase = 'audit_adm'
$BD_Table = 'audit_fs'
$BD_Table = $SQLDateBase + '.dbo.' + $BD_Table
#Подгружаем модуль для работы с SQL, про него можно прочитать тут
Import-Module ("C:\Scripts\SQLDataTools\SQLDataTools.psm1")
#Описываем функцию запросов к базе, что бы упростить структуру скрипта
function Query {Invoke-DatabaseQuery -verbose -connectionString ('Server=' + $SQl_Server + ';Database=' + $SQLDateBase + ';Trusted_Connection=True;') -isSQLServer -query $args[0]}
#Описываем функцию которая будет непосредственно загружать события в базу
function Create_Query {
$STR_Q = $Null
[string]$STR_Q = 'INSERT INTO ' + $BD_Table + ' (SubjectUserName,IpAddress,ShareName,ShareLocalPath,RelativeTargetName,AccessMask,DateEvent,SRV) VALUES (N''' + $args[0] + ''',''' + $args[1] + ''',N''' + $args[2] + ''',N''' + $args[3] + ''',N''' + $args[4] + ''',''' + $args[5] + ''',''' + $args[6] + ''',''' + $args[7] + ''') ;'
Query $STR_Q
}
#Запускаем цикл загрузки и обработки событий из журнала Security с ID 5145
Do{
$Events= $NUll
# Загрузка событий журнала, в зависимости от ОС. Маски указаны в запросе
if( $OS -match '6.1'){$Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID=5145;StartTime=$Start_Time;Data="0x12019f","0x20","0x110080","0x10080"} }
if( $OS -match '6.3'){$Events = Get-WinEvent -FilterHashtable @{LogName="Security";ID=5145;StartTime=$Start_Time;Data="0x10080","0x2","0x100180","0x110080"} }
#######################
If ($Events -ne $Null){
#####
foreach ($Event in $Events){
if ($Events[0] -ne $Null) {
#$Start_Time = (($Events[0]).TimeCreated).AddMilliseconds(1)
$Start_Time = (($Events[0]).TimeCreated).AddMilliseconds(1)
$Start_Time = (($Start_Time).DateTime + '.' + ($Start_Time.Millisecond))
}
$AccessMask = $NUll
$AccessMask = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "AccessMask"}) -replace "^.+>")
$SubjectUserName = $NUll
$IpAddress = $NUll
$ShareName = $NUll
$ShareLocalPath = $NUll
$RelativeTargetName = $NUll
$SubjectUserName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "SubjectUserName"}) -replace "^.+>")
$IpAddress = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "IpAddress"}) -replace "^.+>")
$ShareName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "ShareName"}) -replace "^.+>")
$ShareLocalPath = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "ShareLocalPath"}) -replace "^.+>")
$RelativeTargetName = [string](($Event.ToXml() -split "</Data>" | where {$_ -match "RelativeTargetName"}) -replace "^.+>")
$ShareLocalPath = $ShareLocalPath -replace '\\..\\'
$ShareName = $ShareName -replace "[\\*]"
#условие исключающее не нужные сетевые ресурсы, а также логины пользователей
if(($ShareName -ne 'IPC$') -and ($SubjectUserName -notmatch "s-")) {
#Условие исключающее служебные файлы
if ( ($RelativeTargetName -notmatch "Thumbs.db") -and ($RelativeTargetName -notmatch ".*tmp") -and ($RelativeTargetName -notmatch ".*~$*") -and ($RelativeTargetName -notmatch ".*~lock*")) {
#У каждого события в журнале есть Маска, именно они определяют, что произошло с объектом. Расщифровку можно посмотреть тут
#Расшифровка масок, в зависимости от ОС
if( $OS -match '6.1'){$AccessMask = $AccessMask -replace '0x10080','delete' -replace '0x12019f','write' -replace '0x20','moveTo' -replace '0x110080','moveFrom' }
if( $OS -match '6.3'){$AccessMask = $AccessMask -replace '0x10080','delete' -replace '0x2','write' -replace '0x100180','moveTo' -replace '0x110080','moveFrom' }
Write-Host (($Event.TimeCreated).DateTime + ":" + ($Event.TimeCreated).Millisecond) $SubjectUserName $ShareName\$RelativeTargetName $AccessMask
Create_Query $SubjectUserName $IpAddress $ShareName $ShareLocalPath $RelativeTargetName $AccessMask $Event.TimeCreated $env:computername
}
}
}
}
#######################
#Удаление старых записей старше 180 дней
#Query ('delete From ' + $BD_Table + ' where DateEvent <= cast (dateadd (day, -180, GETDATE()) as DATE)')
echo ("==" + $Start_Time + ":" + $Start_Time.Millisecond)
#Пауза 10 сек перед новым проходом
sleep 10
}While($Stop_Flag -eq $NUll)
После чего, создаем задание в Task Scheduler с расписание после старта компьютера
Не мало важно учесть при этом от какой уч записи будет выполнятся скрипт, так как этой уч записи необходим доступ к базе SQL на запись
На этом настройка клиентской части закончена, на этом этапе мы уже получили рабочую модель клиент-серверного приложения. О создании непосредственно отчетов для событий речь пойдет в третьей части.
Комментариев нет:
Отправить комментарий