Аудит удаления и доступа к файлам и запись событий в лог-файл средствами Powershell
Я думаю, многие сталкивались с задачей, когда к Вам приходят и спрашивают: «У нас тут файл пропал на общем ресурсе, был и не стало, похоже кто-то удалил, Вы можете проверить кто это сделал?» В лучшем случае вы говорите, что у вас нет времени, в худшем пытаетесь найти в логах упоминание данного файла. А уж когда включен файловый аудит на файловом сервере, логи там, мягко говоря «ну очень большие», и найти что-то там — нереально.
Вот и я, после очередного такого вопроса (ладно бекапы делаются несколько раз в день) и моего ответа, что: «Я не знаю кто это сделал, но файл я Вам восстановлю», решил, что меня это в корне не устраивает…
Начнем.
Для начала включим к групповых политиках возможность аудита доступа к файлам и папкам.
Локальные политики безопасности->Конфигурация расширенной политики безопасности->Доступ к объектам
Включим «Аудит файловой системы» на успех и отказ.
После этого на необходимые нам папки необходимо настроить аудит.
Проходим в свойства папки общего доступа на файловом сервере, переходим в закладку «Безопасность», жмем «Дополнительно», переходим в закладку «Аудит», жмем «Изменить» и «Добавить». Выбираем пользователей для которых вести аудит. Рекомендую выбрать «Все», иначе бессмысленно. Уровень применения «Для этой папки и ее подпапок и файлов».
Выбираем действия над которыми мы хотим вести аудит. Я выбрал «Создание файлов/дозапись данных» Успех/Отказ, «Создание папок/дозапись данных» Успех/отказ, Удаление подпапок и файлов и просто удаление, так же на Успех/Отказ.
Жмем ОК. Ждем применения политик аудита на все файлы. После этого в журнале событий безопасности, будет появляться очень много событий доступа к файлам и папкам. Количество событий прямопропорционально зависит от количества работающих пользователей с общим ресурсом, и, конечно же, от активности использования.
Итак, данные мы уже имеем в логах, остается только их оттуда вытащить, и только те, которые нас интересуют, без лишней «воды». После этого акурратно построчно занесем наши данные в текстовый файл разделяя данные симовлами табуляции, чтобы в дальнейшем, к примеру, открыть их табличным редактором.
А теперь очень интересный скрипт.
Скрипт пишет лог об удаленных файлах.
Как оказалось при удалении файлов и удалении дескрипторов создается одно и тоже событие в логе, под При этом в теле сообщения могут быть разные значения «Операции доступа»: Запись данных (или добавление файла), DELETE и т.д.
Конечно же нас интересует операция DELETE. Но и это еще не все. Самое интересное, то что, при обычном переименовании файла создается 2 события с ID 4663, первое с Операцией доступа: DELETE, а второе с операцией: Запись данных (или добавление файла). Значит если просто отбирать 4663 то мы будем иметь очень много недостоверной информации: куда попадут файлы и удаленные и просто переименованные.
Однако мной было замечено, что при явном удалении файла создается еще одно событие с ID 4660, в котором, если внимательно изучить тело сообщения, содержится имя пользователя и еще много всякой служебной информации, но нет имени файла. Зато есть код дескриптора.
Однако предшествующим данному событию было событие с ID 4663. Где как раз таки и указывается и имя файла, и имя пользователя и время, и операция как не странно там DELETE. И самое главное там имеется номер дескриптора, который соответствует номеру дескриптора из события выше (4660, помните? которое создается при явном удалении файла). Значит теперь, чтобы точно знать какие файлы удалены, необходимо просто найти все события с ID 4660, а так же предшествующие каждому этому событию, событие с кодом 4663, в котором будет содержаться номер нужного дескриптора.
Эти 2 события генерируются одновременно при удалении файла, но записываются последовательно, сначала 4663, потом 4660. При этом их порядковые номера различаются на один. У 4660 порядковый номер на единицу больше чем у 4663.
Именно по этому свойству и ищется нужное событие. 
Т.е. берутся все события с ID 4660. У них берется 2 свойства, время создания и порядковый номер.
Далее в цикле по одному берется каждое событие 4660. Выбирается его свойства, время и порядковый номер.
Далее в переменную $PrevEvent заносится номер нужного нам события, где содержится нужная информация об удаленном файле. А так же определяются временные рамки в которых необходимо искать данное событие с определенным порядковым номером (с тем самым который мы занесли в $PrevEvent). Т.к. событие генерируется практически одновременно, то поиск сократим до 2х секунд: + — 1 секунда.
(Да, именно +1 сек и -1 сек, почему именно так, не могу сказать, было выявлено экспериментально, если не прибавлять секунду, то некоторые может не найти, возможно связано с тем, что возможно два эти события могут создаваться один раньше другой позже и наоборот).
Сразу оговорюсь, что искать только по порядковому номеру по всем событиям в течении часа — очень долго, т.к. порядковый номер находиться в теле события, и чтобы его определить, нужно пропарсить каждое событие — это очень долго. Именно поэтому необходим такой маленький период в 2 секунда (+-1сек от события 4660, помните?).
Именно в этом временном промежутке ищется событие с необходимым порядковым номером.
После того как оно найдено, работают фильтры:
Т.е. не записываем информацию об удаленных временных файлах (.*tmp), файлах блокировок документов MS Office (.*lock), и временных файлах MS Office (.*
$*)
Таким же образом берем необходимые поля из этого события, и пишем их в переменную $BodyL.
После нахождения всех событий, пишем $BodyL в текстовый файл лога.
Для лога удаленных файлов я использую схему: один файл на один месяц с именем содержащим номер месяца и год). Т.к. удаленных файлов в разы меньше чем файлов к которым был доступ.
В итоге вместо бесконечного «рытья» логов в поисках правды, можно открыть лог-файл любым табличным редактором и просмотреть нужные нам данные по пользователю или файлу.
Рекомендации
Вам придется самим определить время в течении которого вы будете искать нужные события. Чем больше период, тем дольше ищет. Все зависит от производительности сервера. Если слабенький — то начните с 10 минут. Посмотрите, как быстро отработает. Если дольше 10 минут, то либо увеличьте еще, вдруг поможет, либо наоборот уменьшите период до 5 минут.
После того как определите период времени. Поместите данный скрипт в планировщик задач и укажите, что выполнять данный скрипт необходимо каждые 5,10,60 минут (в зависимости какой период вы указали в скрипте). У меня указано каждый 60 минут. $time = (get-date) — (new-timespan -min 60).
Аудит удаления файлов в сетевой папке на Windows Server
16.11.2022
itpro
Windows Server 2012 R2
комментария 62
С помощью аудита событий доступа к объектам файловой системы вы можете определить конкретного пользователя, который создал, удалил или изменил определенный файл. В этой статье мы покажем, как настроить аудит событий удаления объектов в общей сетевой папке на Windows Server 2016. После настройки аудита, вы можете с помощью информации в журнале событий найти пользователя, который удалил на файловом сервере.
Включаем политику аудита доступа к файлам и папкам в Windows
По умолчанию в Windows Server не включен аудит событий доступа к объектам на файловой системе. Вы можете включить и настроить аудит событий с помощью групповой политики. Если нужно включить политики аудита на нескольких серверах или компьютера, можно использовать доменные GPO (настраиваются с помощью консоли управления gpmc.msc). Если нужно настроить аудит только на одном сервере, можно воспользоваться локальной групповой политикой.
- Запустите консоль редактора локальной политики – gpedit.msc ;
- Перейдитевраздел GPO срасширенными политиками аудитаWindows Settings -> Security Settings -> Advanced Audit Policy Configuration -> Object Access;
- Откройте политику Audit File System и укажите, что вы хотите сохранять в журнал только успешные события доступа к объектам файловой системы (Configure the following audit events -> Success);
Настройка аудита событий удаления файлов из конкретной папки
Теперь нужно настроить аудит в свойствах общей сетевой папки, доступ к которой вы хотите отслеживать. Запустите проводник и откройте свойства общей папки. Перейдите на вкладку Security. Нажмите кнопку Advanced -> вкладка Auditing.
Если появится сообщение You must be an administrator or have been given the appropriate privileges to view the audit properties of this object, нажмите кнопку Continue.

Затем нажмите кнопку Add чтобы указать пользователя или группу, для которых нужно записывать все события аудита. Если вы хотите отслеживать события для всех пользователей, укажите группу Everyone.
Затем нужно указать использование каких разрешений доступа к объекту нужно записывать в лог. Чтобы сохранять в Event Log только события удаления файлов, нажмите кнопку Show advanced permissions. В списке событий оставьте аудит только для событий удаления папок и файлов — Delete и Delete subfolders and files.

$Path = «D:\Public»
$AuditChangesRules = New-Object System.Security.AccessControl.FileSystemAuditRule(‘Everyone’, ‘Delete,DeleteSubdirectoriesAndFiles’, ‘none’, ‘none’, ‘Success’)
$Acl = Get-Acl -Path $Path
$Acl.AddAuditRule($AuditChangesRules)
Set-Acl -Path $Path -AclObject $Acl
Теперь, если пользователь удалит любой файл или папку в сетевой папке, в журнале безопасности системы появляется событие File System -> Audit Succes c Event ID 4663 от источника Microsoft Windows security auditing.
Откройте mmc консоль Event Viewer ( eventvwr.msc ), разверните секцию Windows Logs -> Security. Включите фильтр событий по EventID 4663.

Откройте любой их оставшихся событий в Event Viewer. Как вы видите, в нем есть информация об имени удаленного файла и учетной записи пользователя, который удалил файл.

После настройки аудита, найдите в журнале Security вы сможете найти с:
- Кто и когда удалил файл в сетевой папке;
- Из какого приложения удален файл;
- На какой момент времени нужно восстанавливать бэкап данного каталога.
Запись событий удаления файлов в SQL базу (MySQL/MSSQL)
Если после включения аудита удаления файлов в сетевой папке, вы видите в журнале много событий, найти что-то в логах бывает проблематично. Во-первых, найти нужную запись среди тысячи событий довольно сложно (в Windows отсутствуют вменяемые средства поиска интересующего события с возможностью гибкой фильтрации), а во-вторых, если файл был удален давно, это событие может просто отсутствовать в журнале, т.к. было перезатерто более новыми.
Вы можете записывать все нужные событий в отдельную SQL базу данных. Для хранения событий можно использовать Microsoft SQL Server, Elasticsearch или MySQL/MariaDB.
В этом примере мы покажем, как записывать события аудита в отдельную таблицу БД на сервере MySQL. Формат таблицы:
- Имя сервера;
- Имя удаленного файла
- Время удаления;
- Имя пользователя, удалившего файл.
MySQL запрос на создание такой таблицы будет выглядеть так:
CREATE TABLE track_del (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
Если вы хотите использовать Microsoft SQL, обратите внимание на статью “Как выполнить запрос к MSSQL Server из скрипта PowerShell?”.
Для получения событий с EventID 4663 из журнала Security за текущий день можно использовать такой PowerShell скрипт:
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @
$event = [xml]$_.ToXml()
if($event)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$User = $event.Event.EventData.Data[1].»#text»
$Computer = $event.Event.System.computer
>
>

Следующий PowerShell скрипт запишет полученные данные в БД MySQL на удаленном сервере:
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll’
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@
$Connection.Open()
$sql = New-Object MySql.Data.MySqlClient.MySqlCommand
$sql.Connection = $Connection
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @
$event = [xml]$_.ToXml()
if($event)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$File = $File.Replace(‘\’,’|’)
$User = $event.Event.EventData.Data[1].»#text»
$Computer = $event.Event.System.computer
$sql.CommandText = «INSERT INTO track_del (server,file_name,dt_time,user_name ) VALUES (‘$Computer’,’$File’,’$Time’,’$User’)»
$sql.ExecuteNonQuery()
>
>
$Reader.Close()
$Connection.Close()
Теперь, чтобы узнать, кто удалил файл «document1 — Copy.DOC». Достаточно в консоли PowerShell выполнить следующий скрипт.
$DeletedFile = «%document1 — Copy.DOC%»
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v4.5\MySql.Data.dll’
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@
$Connection.Open()
$MYSQLCommand = New-Object MySql.Data.MySqlClient.MySqlCommand
$MYSQLDataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter
$MYSQLDataSet = New-Object System.Data.DataSet
$MYSQLCommand.Connection=$Connection
$MYSQLCommand.CommandText=»SELECT user_name,dt_time from track_del where file_name LIKE ‘$DeletedFile'»
$MYSQLDataAdapter.SelectCommand=$MYSQLCommand
$NumberOfDataSets=$MYSQLDataAdapter.Fill($MYSQLDataSet, «data»)
foreach($DataSet in $MYSQLDataSet.tables[0])
<
write-host «User:» $DataSet.user_name «at:» $DataSet.dt_time
>
$Connection.Close()
В результате в консоли PS появится имя пользователя и время удаления файла.

Скрипт сброса данных из журнала в БД можно выполнять один раз в конце дня по планировщику или повесить триггер на событие удаления (On Event), что более ресурсоемко. Все зависит от требования к системе.
Можно создать реагировать простую веб страницу на php для получения информации о событиях удаления файлов в более удобном виде. Задача решается силами любого php программиста за 1-2 часа.
Запись информации о событиях удаления файлов в текстовый файл
Если вы не хотите вести отдельную БД, можно сохранять события аудита удалений файлов в текстовый лог файл. Воспользуйтесь таким PowerShell скриптом:
$Outfile = «C:\ps\delete-file-log.txt»
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @
$event = [xml]$_.ToXml()
if($event)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$User = $event.Event.EventData.Data[1].»#text»
$strLog = $Computer + » » + $File + » » + $Time + » » + $User
$strLog | out-file $Outfile –append
>
>

Итак, мы предложили идею и некий общий каркас системы аудита и хранения информации об удаленных файлах в сетевых шарах, при желании ее с лёгкостью можно будет модифицировать под ваши нужды.
Предыдущая статья Следующая статья



alt=»Схема работы KMS активации» width=»58″ height=»56″ /> FAQ по KMS активации продуктов Microsoft (Windows и Office)
alt=»Установка FSRM в Windows 2012 R2″ width=»58″ height=»56″ /> Защита от шифровальщиков с помощью FSRM в Windows Server
alt=»tsadmin.msc не работет на Windows Server 2012 R2″ width=»58″ height=»56″ />Использование TSADMIN.msc и TSCONFIG.msc для управления RDS в Windows Server 2019/2016/2012R2
alt=»Windows ACME Simple скачать с github» width=»58″ height=»56″ />Установка бесплатного TLS/SSL сертификата Let’s Encrypt в IIS/RDS в Windows Server 2016/2012 R2
Предполагается, видимо, что MySQL уже установлен и настроен?
100 лет уже не имел дела с «мускулом»…
Да, конечно. Причем он даже под Windows ставится несколькими кликами.
В общем-то код и всю технику можно легко адаптировать и под MSSql, но с точки зрения зрения легкости, отдаю предпочтению мусклу.
Извини если туплю, но из статьи НЕ очевтдно
куда засунуть и как запустить скрипт
«Скрипт сбора информации из журнала событий. Мы фильтруем журнал по событию с ID 4663 за текущий день»
а за ним все остальные
Подразумевал, что раз в сутки планировщик (допустим в 23:58) запускает powershell скрипт, который получает все события за прошедшие сутки и пишет из в базу.
Т.е. в создаем задание планировщика, которое запускет программу C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe с аргументом в виде имени файла со вторым скриптом C:\myscripts\WriteDelEventDB.PS1
«Скрипт сбора информации из журнала событий» — это просто пример работы с журналом событий, фильтрации и получения значений определенных полей. Он используется внутри следующего скрипта.
Что-то пошло не так. Или — что я сделал не так?
На первой же строке скрипта вылезает матершина:
(все делается под одним из Domain Admin аккаунтов)
PS C:\Users\admin> Get-WinEvent -FilterHashTable @
Get-WinEvent : Could not retrieve information about the Security log. Error: Attempted to perform
an unauthorized operation..
At line:1 char:1
+ Get-WinEvent -FilterHashTable @
+
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : LogInfoUnavailable,Microsoft.PowerShell.Commands.GetWinEventCommand
Get-WinEvent : There is not an event log on the localhost computer that matches «Security».
At line:1 char:1
+ Get-WinEvent -FilterHashTable @
+
+ CategoryInfo : ObjectNotFound: (Security:String) [Get-WinEvent], Exception
+ FullyQualifiedErrorId : NoMatchingLogsFound,Microsoft.PowerShell.Commands.GetWinEventCommand
+ CategoryInfo : NotSpecified: (:) [Get-WinEvent], EventLogException
+ FullyQualifiedErrorId : System.Diagnostics.Eventing.Reader.EventLogException,Microsoft.Power
Shell.Commands.GetWinEventCommand
Пардону просим
Run As Administrator забыл сделать Ж-)
Здравствуйте, отличная статья. Решал подобную задачу для сбора статистики с KMS сервера, но использовал связку PS и MSSQL Express. Через год работы наткнулся на проблему, что превысил лимит базы данных в 10Гб, в итоге сделал ротацию данных в БД Наверное в вашем случае тоже было бы неплохо предусмотреть удаление старых данных? Могу поделиться наработками, если интересно.
Приветствую,
Насчет удаления старых данных пока не думал. Сложно оценить насколько будет большой база и за какой период нужна информация. Здесь больше идея рассматривается, какие-то выводы и усовершенствования можно делать только после опыта более продолжительного использования.
А инфой конечно, делитесь! Можно оформить отдельной статьей, думаю тема сбора и хранения статистики использования KMS сервера будет многим интересна.
Мой емайл есть на странице https://winitpro.ru/index.php/o-bloge/
Странно как-то себя MySQL повел ….
Поставил, для удобства, Navicat Premium Enterprise 11.2.4
)
и получается как-то странно
если делать, этим Navicat, Export всей таблицы из базы, то в поле file_name попадает имя файла целиком (правда отделенное пробелом почему-то от всего остального)
а когда делаешь select … то имя файла обрезается до полного пути до него
SELECT track_del.file_name,track_del.dt_time,track_del.user_name FROM track_del
а на выходе
file_name dt_time user_name
DeviceHarddiskVolume2TEST 2016-05-05 12:12:24 name
Если присмотреться, то в поле file_name попадается пробел. И, походу, по нему и режется. А пока оно так себя ведет, дальше ничего не работает. То есть невозможно сделать LIKE по значению, которое не показывается
Починил.
В скрипте, который заполняет таблицу в БД, вставил строку, которая меняет в имени файла, получаемого из Security Even Log’a все ‘\’ на ‘|’ Вот здесь:
После этого имя файла перестало «теряться» и попадает в БД как надо
И потом, слегка «доработал» скрипт, который выдает результат. Мне плказалось так и красивее, и правильнее. Добавлен вывод имени файла с полным путем. с обратной заменой ‘|’ на ‘\’
foreach($DataSet in $MYSQLDataSet.tables[0])
<
write-host «File:» $DataSet.file_name.Replace(‘|’,’\’) — «User:» DataSet.user_name «at:» $DataSet.dt_time
>
А ведь это был _очень_неприятный баг MySQL, на самом деле
Файл, на котором я «тренировался», я назвал 00000.txt (5 нулей) и, в итоге, в базу из Event Log’a попадало вот что
DeviceHarddiskVolume2TEST 0000.txt
То есть при выполнении INSERT MySQL «выгрызал» все символы ‘\’ и, более того делал из подстроки 0000.txt такое вот «[SPACE]0000.txt» типа пытался «интерпретировать по своему»?
А после того как я, предварительно, заменял все ‘\’ на ‘|’ — все проходило как надо
Дмитрий, думаю не лишним будет или упомянуть об этой «особенности» или поправить скрипт, который заносит имя файла в таблицу БД.
Видимо проблема в сочетании «\»+»0» , которое как-то интерпретируется mysql, то ли пустая строка, то ли что-то в этом роде.
Согласен, в скрипте лучше всего заменить ‘\’ на ‘|’, а при выборке делать обратную замену.
Сейчас внесу изменения в статью. Спасибо!
А что скажете про [regex]::Escape(‘c:\’) ?
Я подобную штуку сейчас проворачиваю, но отправляю пошиком не напрямую в базу, а через пхп, так вот эскейп работает как надо. Мне интересно как будут обстоять дела, если пошиком напрямую в базу лить, но сам пробовать не хочу ))
Коллеги кто нибуть настраивал данную возможность с помощью SCOM?
Есть ли информация по данному вопросу,может быть кто то уже имел опыт,заранее спасибо за ответ.
Для настройки мониторинга данного EventID нужно в SCOM создать новое правило (Rule).
Правило создаём тут: Authoring -> Management Pack Objects -> Rules.
При создании указываем Type: Alert Generating Rules -> Event Based -> NT Event Log (Alert); Rule target: Windows Domain controller, Log Name: Security, Event ID eq 4663. Затем нужно привязаться к новому правилу действие в Subscription.
Странная команда в скрите
«Следующий скрипт запишет полученные данные в БД MySQL на удаленном сервере:»
вот эта
PowerShell ругается на нее. Наверное и правильно. Ведь закрывается то, что не открывалось.
А для Win2k как сделать подобное?
В нем аудит естьт, политика безопасности — есть, а события 4663 не выдается (((
Может кто сталкивался?
ID события скорее всего другие, да и не факт что PowerShell вообще заведется на W2k..
ЗЫ. Закапывайте мамонта
MySQL запрос на создание такой таблицы будет выглядеть так:
CREATE TABLE track_del (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
результат.
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near ‘AUTO_INCREMENT’.
Здраствуйте. Никогда раньше ни делал ничего подобного. Со второго раза вроде получилось. У меня вопрос в событии у меня есть строка » 192.168.201.153″ как добавть дополнительный столбец в таблицу и как в него записывать Ip адресс?
добрый день.
собран кластер на WS2016.
Есть CSV. Эту шару я и хочу логировать. Делаю все по инструкции, но когда что-либо оттуда удаляю, нет записи в логах Security.
Был ли опыт проведения аудита на кластерной шаре?
Спасибо. Хорошая статья.
Под рукой такой конфигурации нет. Могу посоветовать
1) проверить, что политики аудита применяются для обычных шар (записи в логе появляются).
2) в случае CSV возможно стоит проверять все логи на всех нодах кластера
1) работает, идеально.
2) проверяю на всех, к сожалению нет.
Запускай на каждой ноде. В Скрипте проверяй кто владеет нодой:
$ClusterRoleOwner = (Get-ClusterGroup | Where-Object <($_.Name -eq «ИМЯ ТВОЕЙ РОЛИ»)>).OwnerNode
если тот кто надо, то читаешь логи:
if ($ClusterRoleOwner -eq $env:computername)
Отличный каркас для работы с логами. После лёгкой косметической допилки всё полетело на MSSQL Express 2014 ADV (ставить на сервер вторую СУБД смысла нет). Бага с чир-символом в этой версии MSSQL нет. Всё загружается и выгружается чётко.
Спасибо автору))
Спасибо! Очень полезная вещь!
Пожалуйста подскажите, как быть с кириллицей в имени каталогов и файлов? В таблице вместо кириллицы знаки вопроса «…. |. docx».
Что делать с русской кодировкой в именах файлах, к сожалению, не знаю. Как вариант — экспортировать журналы в csv файлы. А потом при загружать их через Get-Content -Encoding UTF8. Но это на уровне идеи…
Для правильного сохранения кириллицы добавьте в конец строки «charset=utf8»
Должно получится так
$Connection = [MySql.Data.MySqlClient.MySqlConnection]@
Отлично! Спасибо за полезную инфу!
Доброго времени суток. Попробовал, все равно «. |. pdf»
Спасибо огромное. Разобрался. Нужно было сменить кодировку в самой БД на utf8_unicode_ci.
Для работы с любыми логами использую graylog community edition можно купить enterprise edition , и там делаю с логами что угодно
А что для визуализации данных и логов используете (графические дашборды, отчеты)?
С Elasticsearch обычно используют Kibana. А что у graylog как аналог?
PS C:\WINDOWS\system32> $event = [xml]$_.ToXml()
Невозможно вызвать метод для выражения со значением NULL.
строка:1 знак:1
+ $event = [xml]$_.ToXml()
+
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
Какая ОС и версия PowerShell?
Windows Server 2012 R2 6.3.9600.18969 64-разрядная
Version PS : 5.1.14409.1018
Странно у меня в такой же конфигурации все работает. Windows Server случайно не русская? Я такую принципиально не пользую, только eng.
Нет. Проверил в 10-ке (правда «русской») — тоже такая же «петрушка»
Ну вот у меня код работает даже в русской Windows….
Запускаете в PowerShell ISE под админом?
Да, под админом
Не работает
А если удалять файлы с помощью Shift+DEL, то регистрируется только событие с id 4659. По крайней мере у меня на Windows Server 2012 так.
Здравствуйте, у нас стоят 2 сервера с Windows 2019, и на них установлен DFS с авторепликацией на оба сервера.
В результате у нас нет нормального аудита: в списках по событию 4663 (мы используем дополнительно фильтр по маске 0х10000, что предположительно соответствует операции DELETE) есть файлы с названиями типа
D:\System Volume Information\DFSR\Private\
(это после удаления всех файлов типа .log, .tmp и \
$ ). Причём в качестве пользователя стоит имя сервера.
Ещё есть удаления целых каталогов (?!), тоже с именем сервера. В поле ProzessName стоит C:\Windows\System32\dfsrs.exe
Есть и удаления от конкретных пользователей, но от них идут несколько удалений одних и тех же файлов — это вероятно результаты неоднократных редактирований того же файла… При этом поле ProzessName вообще пустое!
Вопрос: каким образом можно обнаружить удаления при использовании DFS ?
Колеги а как очистить журнал после того, как витянул данные с журнала?
Я же буду на постой дозаписывать то, что уже есть.
Нужно искать пару : id 4663 а потом 4660 с аналогичным кодом дескриптора в двух событиях. Тогда это будет реальное удаление.
https://docs.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4660
Доброго времени, уважаемые коллеги!
У меня сервер 2008. Сделал всё как тут написано, получилось на ура. Но хотелось бы задать вопрос. В событиях по коду 4663 регистрируется только пользователь и действия с файлом, которые он инициировал. Но хотелось бы в событиях поиметь или имя компа или его айпишник. Думал, на 2008 серваке такого нет, а есть в более поздних серверных версиях, но нет. На работе посмотрел, также без айпишников логи ведутся.
Есть ли возможность добавить в событие 4663 IP или имя компа? Хочу вычислить, откуда вирусня прёт, а то в этой организации многие сидят под одним логином. Я говорю, давайте каждому учётку заведём. Нет, говорят. Нам так удобнее. Ну что с такими делать?
Имеено это событие вы никак не расширите. Тут нужно скорре всего нужно дополнительно анализировать события логона компьютера на ваш сервере из журнала Security. Скорее всего они будут связаны по logonID или handleID. И уже из события логона вытягивать имя компьютера.
Сначала попробуйте вручную разобраться с ID события и их связью с 4663 . Пришлите инфу сюда, может помогу в чем.
Спасибо за статью. Пришлось исправить, т.к. у меня Server 2008 R2 (соответственно там старая версия Powershell), данные выгружаются в MySQL 5.0.95, который находится на другом старом Linux сервере:
1) В базе выполнил SQL-запрос:
SET SESSION old_passwords=0;
SET PASSWORD FOR db_user_name=PASSWORD(‘db_user_password’);
2) Скрипт выглядит так:
Set-ExecutionPolicy RemoteSigned
Add-Type –Path ‘C:\Program Files (x86)\MySQL\MySQL Connector Net 6.9.8\Assemblies\v2.0\MySql.Data.dll’
$connectionString = «server=server_IP;uid=db_user_name;pwd=db_user_password;database=db_name;»
$connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$sql = New-Object MySql.Data.MySqlClient.MySqlCommand
$sql.Connection = $Connection
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @
$event = [xml]$_.ToXml()
if($event)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$File = $File.Replace(‘\’,’|’)
$User = $event.Event.EventData.Data[1].»#text»
$Computer = $event.Event.System.computer
$sql.CommandText = «INSERT INTO track_del (server,file_name,dt_time,user_name ) VALUES (‘$Computer’,’$File’,’$Time’,’$User’)»
$sql.ExecuteNonQuery()
>
>
$Connection.Close()
3) Создал задание в планировщике с такими параметрами:
Вкладка Общие:
-выполнять вне зависимости от регистрации пользователя
-выполнять с наивысшими правами
-выполнять от учетки админа домена
Вкладка Триггеры:
-начать задачу при событии
-Параметры: Простое, Журнал — Безопасность, Источник — Microsoft Windows security auditing, Код события — 4663
-внизу галочка — Включено
Вкладка Действия:
-Действие — Запуск программы
-Программа или сценарий: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
-Добавить аргументы: E:\scripts\file_del_to_db.ps1 (путь к скрипту)
Вкладка Параметры:
-Разрешать выполнение задачи по требованию
-Останавливать задачу, выполняемую дольше: 3 дн.
-Принудительная остановка задачи, если она не прекращается по запросу
-Если задача уже выполняется, то применять правило: Не запускать новый экземпляр.
Ну и при сохранении задачи естественно нужно будет ввести пароль пользователя, от имени которого она будет выполняться (у меня учетка админа домена).
Теперь особенность. За 1,5 дня у меня в базе 8000 записей. Как бы много, и не очень удобно в случае чего искать нужные.
Просьба к автору статьи, не могли бы Вы изменить скрипт так, чтобы данные в базу писались каждый день в отдельные таблицы или как-то по-другому их отделить, а также сделать исключение файлов, например, по расширению (а то пользователи напрямую открывают по сети файлы Microsoft Office и в базу потом пишутся записи об удалённых файлах *.tmp). Спасибо))).
За инфу спасибо.
1) Писать в разные таблицы? а зачем, не проще фильтровать записи по дате.
2) Чтобы писать инфу только по нужным расширениям файлам, просто сделайте дополнительную проверку содержимого $File на соответствие нужным расширениям файлов перед запись в базу:
$allowedext = @(‘.doc’,’.docx’,’.xlsx’,’.xls’)
$fileext=[System.IO.Path]::GetExtension($file)
if ($allowedext -match $fileext’)
<
write to db
>
Спасибо за ответ. Не могу точно знать какие типы файлов там есть, т.к. структура папок огромная, всего примерно 2 млн. файлов))) Конечно и ненужные есть, но рыться там у меня нет желания, у каждого отдела своя папка… короче там чёрт ногу сломит))). Поэтому вышел из положения так:
1) Перенес базу на новый Linux сервер, там 10.3.28-MariaDB. В ней есть уже планировщик заданий.
2) В phpmyadmin создал задачу, которая каждый день в 00:00 удаляет из базы записи о файлах *.tmp.
Параметры задачи такие:
Название события: file_del_tmp_every_day
Состояние: ENABLED
Тип события: RECURRING
Выполнять каждые: 1 DAY
Начало: 2021-05-14 00:00:00
Конец: (Пусто)
Определение: delete from `db_name`.`track_del` where file_name like ‘%.tmp’
Сохранить при окончании: (Поставил галочку)
Определитель: root@localhost
Также нужно не забыть:
Статус планировщика событий: Включить
Пока пусть будет так. Правда с 14 мая 2021 до сегодня (21 мая 2021) размер базы 114 МБ и количество строк примерно 530000))). Жесть конечно, пока не знаю что с этим делать))).
Из личных наблюдений. События 4660 и 4663 появляются при локальном удалении из локальной или сетевой папки, т.е. пользователь совершил локальный вход на сервер и удаляет файл с диска или из папки в общем доступе. Событие 4659 — при сетевом удалении из сетевой папки. Так что как применять статью не понятно.
Скрипт записи в текстовый файл дополненный выборкой только по удаленным файлам:
$Outfile = «C:\ps\delete-file-log.txt»
$today = get-date -DisplayHint date -UFormat %Y-%m-%d
Get-WinEvent -FilterHashTable @
$event = [xml]$_.ToXml()
if($event.Event.EventData[9].’#text’ -eq ‘0x10000’)
<
$Time = Get-Date $_.TimeCreated -UFormat «%Y-%m-%d %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$User = $event.Event.EventData.Data[1].»#text»
$strLog = $Computer + » » + $File + » » + $Time + » » + $User
$strLog | out-file $Outfile –append
>
>
Корректировка) пропустил Data[9]
$event.Event.EventData.Data[9]
Статья нужная, но нам нужно было на создание файлов в обмене и отправлялся отчет. Добавили в планировщик задачу с выполнением скрипта. Если кому нужно сам скрипт:
$Outfile = «D:\audit.txt» #$(Get-Date -UFormat «%d-%m-%Y_%H_%M_%S»).txt» — у меня сохраняет в единый файл, но кому надо будет создавать ежедневный отчет.
$today = [datetime]::Today.AddDays(-5) #Get-Date -DisplayHint date -UFormat %d-%m-%Y Указал за последние 5 дней сбор данных
$strLog = @()
Get-WinEvent -FilterHashTable @ < LogName = "Security"; starttime = $today; | Foreach <
$event = [xml]$_.ToXml()
if($event) <
$Time = Get-Date $_.TimeCreated -UFormat «%d-%m-%Y %H:%M:%S»
$File = $event.Event.EventData.Data[6].»#text»
$User = $event.Event.EventData.Data[1].»#text»
If ($User -notmatch «SERVER\$|LOCAL SERVICE» -and $File -match «F:\\obmen») < # исключаем наименование сервера SERVER\$|LOCAL SERVICE (у вас будет имя иначе) и включать только записи с расположением папки obmen
$strLog += $Time + » » + $User + » » + $Computer + » » + $File
>
>
>
$strLog | out-file $Outfile
#Отправляем письмо с отчетом о проведении аудита
$ToAddress /cdn-cgi/l/email-protection» data-cfemail=»81c8c3e0e5ecc1f1eee2e9f5e0aff3f4″>[email protected]»
$CcAddress /cdn-cgi/l/email-protection» data-cfemail=»420b0023262f7302322d212a36236c3037″>[email protected]»
$FromAddress /cdn-cgi/l/email-protection» data-cfemail=»7d121f1018133d0d121e15091c530f08″>[email protected]»
$SmtpServer = «mail.pochta.ru»
$sabj = «Аудит обмена»
$text = «text»
$mailparam = @ <
To = $ToAddress
Cc = $CcAddress
From = $FromAddress
Subject = $sabj
Body = $text
SmtpServer = $SmtpServer
Attachments = «d:\audit.txt»
>
Send-MailMessage @mailparam -Encoding UTF8
А можно пример скрипта который в текстовой файл записывает удаленные и редактируемые объекты
(вывод в формате расположение файла-время-пользователь-действие)
Отличная статья, спасибо!
Правда у меня не всё получилось. На некоторых подпапках отключено наследование прав по аудиту и устанавливая аудит на родительскую папку, внутри на часть папок аудит так и не доезжает. Пробовал рекурсией пройтись по всем каталогам, но в таком случае права аудит выставляются на каждый каталог в отдельности.
Может есть идеи, как найти все подпапки с отключённым наследованием прав аудита и включить наследование на них?
Можно вывести папки (включая вложенные), для которых не включено наследование с помощью PowerShell:
DIR «C:\Folder» -directory -recurse | GET-ACL | where <$_.Access.IsInherited -eq $false>
Нужно что бы когда пользователь удаляет файл/папку приходило уведомления об этом на почту админа. С этим все ок. Через task shedule настроено на конкретный eventid запуск powershell скрипта, уведомления приходит но проблема в том что когда пользователь удаляет файл/папку приходит несколько писем одновременно (доступ на файл, удаления и др.). А мне нужно только удаления. Фильтировать с помощью 4660 не получилось так как разные действия (доступ,удаления и т.д.) приходят под одну категорию. Нащел решения переходить на ID 4656, там тоже получаем несколько уведомлений при одном удаление, но фильтровать чистое удаления можно с помощью категории (выбрав «Файловая система»), но никак не могу заставить работать фильтр под категорию (например: Where-Object <$_.Category -match 12800>).
Буду благодарен за идею.
$A = Get-WinEvent -MaxEvents 1 -FilterHashTable @
$EventID = $A.Id
$MachineName = $A.MachineName
$Source = $A.ProviderName
$Password = Get-Content «C:\fy.txt» | ConvertTo-SecureString
$EmailFrom /cdn-cgi/l/email-protection» data-cfemail=»e6928395928b878f8aa68b878f8ac885898b»>[email protected]»
$EmailTo /cdn-cgi/l/email-protection» data-cfemail=»e3d1978690978e828a8fa38e828a8fcd808c8e»>[email protected]»
$Subject =»Alert From $MachineName»
$Body = «EventID: $EventID`nSource: $Source`nMachineName: $MachineName `nMessage: $Message»
$SMTPServer = «smtp.office365.com»
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential(«[email protected]», $Password);
$SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
Добрый день! Сделал все по инструкции , но возникла проблема. Когда удаляю папку , в логах записывается, но когда удаляю файл , в логах ничего не пишется
Посмотрите в настройках аудита папки, что выбран режим This folder, subfolder and files.
Как посмотреть кто удалил файл из общей папки
Вирусов точно нет, т.к. стоит NOD32.
гы.
как самонадеяно.
Подробнее можно, какие файлы, как, когда удаляет. Пока версий много: начиная от мастера очиски рабочего стола (он, сцука, ярлыки трет :gigi: ), заканчивая NOD32.
Вам смешно. А меня пытаются подставить. Конечно есть свидетели, что я здесь ничего не удалял, да и вообще за компы не садился.
Подробнее можно, какие файлы, как, когда удаляет.
Всякие *.doc, exel`евские, картинки, файлы баз данных и т.п.
Помогите поймать вредителя.
1. Заходим в LSP: Start -> Settings -> Control Panel -> Administrative tols -> local security policy
2. Включаем аудит доступа к файлам: Local policy -> Audit Policy. Выставляем Object Access в Success, Failure.
3. Выделяем папку, откуда исчезают файлы. Смотрим её свойства -> Security
4. На закладке Security выбираем Advanced, далее — Auditing. Жмём Add.
5. Выбираем группу Everyone, жмём на Check names (название должно подчеркнуться). Жмём ОК
6. Выбираем Delete, всё закрываем.
Потом смотрим в Event Viewer -> Security, ищем нужные файлы
Локальная политика безопасности -> Локальные политики -> Политика аудита.
Аудит доступа к объектам выставляю Отказ.
Выделяю папку -> Свойства -> Безопасность -> Дополнительно -> Аудит -> Добавить
Выбрал группу "Все", нажал "Проверить имена". Жму Ок.
Далее, выбрать Удаление и поставить галочки. А где именно в столбцах: Успех и Отказ, или только отказ?
ruslansstu1146494329
В общем я поставил в политике аудита -> Аудит доступа к объектам: Успех и Отказ.
ruslansstu1146494940
Решил все это дело проверить.
Создал папку, скопировал туда несколько файлов и с другой машины по сети решил удалить. Во что я получил:
Тип события: Аудит успехов
Источник события: Security
Категория события: Доступ к объектам
Код события: 560
Дата: 01.05.2006
Время: 18:41:56
Пользователь: NATASHA\Администратор
Компьютер: NATASHA
Описание:
Открытие объекта:
Сервер объекта: Security
Тип объекта: File
Имя объекта: D:\Руслан\Копия Wine\Linux College.files
Код дескриптора: 2276
Код операции:
Код процесса: 4
Имя файла рисунка:
Основной пользователь: NATASHA$
Домен: COMPAUD
Код входа: (0x0,0x3E7)
Пользователь-клиент: Администратор
Домен клиента: NATASHA
Код входа клиента: (0x0,0xA7881)
Доступ DELETE
Привилегии —
Счетчик ограниченного SID: 0
Жаль, что не пишет с какой машины произведено удаление.
Жаль, что не пишет с какой машины произведено удаление.
Всё прекрасно пишет. Комп "NATASHA".
NaimaD1146518236
Компьютер: NATASHA
Жаль, что не пишет с какой машины произведено удаление.
Всё прекрасно пишет. Комп "NATASHA".
Компьютер: NATASHA
э-э-э. дело в том, что комп НАТАША — это тачка, на которой был запущен Эвент Вьюер, то бишь комп, на котором удаляли файлы, а не с которого удаляли файлы; думается, в одноранговой сетке узнать (только средствами оси) кто удалял — не карма
Пользователь: NATASHA\Администратор
хмм. и одноранговая сеть
Это говорит о том, что удаляют локально. из под учетки локального администратора.
Т.е. это может быть radmin или аналог, telnet (или опять-же аналог) или вредный сервис — прога.
или удалают по сети подключаясь к этому компу под логин-паролем админа — сменить — проверить.
В пакет friendly pinger http://www.kilievich.com/fpinger/ входит логгер сетевых подключений. (по IP)
Сожно попробовать.
Или чтоб наверняка, filemon от sysinternals. Так определишь приложение, которое удаляет. но придется ловить момент.
Аудит удаления и доступа к файлам и запись событий в лог-файл средствами Powershell

Я думаю, многие сталкивались с задачей, когда к Вам приходят и спрашивают: «У нас тут файл пропал на общем ресурсе, был и не стало, похоже кто-то удалил, Вы можете проверить кто это сделал?» В лучшем случае вы говорите, что у вас нет времени, в худшем пытаетесь найти в логах упоминание данного файла. А уж когда включен файловый аудит на файловом сервере, логи там, мягко говоря «ну очень большие», и найти что-то там — нереально.
Вот и я, после очередного такого вопроса (ладно бекапы делаются несколько раз в день) и моего ответа, что: «Я не знаю кто это сделал, но файл я Вам восстановлю», решил, что меня это в корне не устраивает…
Начнем.
Для начала включим к групповых политиках возможность аудита доступа к файлам и папкам.
Локальные политики безопасности->Конфигурация расширенной политики безопасности->Доступ к объектам
Включим «Аудит файловой системы» на успех и отказ.
После этого на необходимые нам папки необходимо настроить аудит.
Проходим в свойства папки общего доступа на файловом сервере, переходим в закладку «Безопасность», жмем «Дополнительно», переходим в закладку «Аудит», жмем «Изменить» и «Добавить». Выбираем пользователей для которых вести аудит. Рекомендую выбрать «Все», иначе бессмысленно. Уровень применения «Для этой папки и ее подпапок и файлов».
Выбираем действия над которыми мы хотим вести аудит. Я выбрал «Создание файлов/дозапись данных» Успех/Отказ, «Создание папок/дозапись данных» Успех/отказ, Удаление подпапок и файлов и просто удаление, так же на Успех/Отказ.
Жмем ОК. Ждем применения политик аудита на все файлы. После этого в журнале событий безопасности, будет появляться очень много событий доступа к файлам и папкам. Количество событий прямопропорционально зависит от количества работающих пользователей с общим ресурсом, и, конечно же, от активности использования.
Итак, данные мы уже имеем в логах, остается только их оттуда вытащить, и только те, которые нас интересуют, без лишней «воды». После этого акурратно построчно занесем наши данные в текстовый файл разделяя данные симовлами табуляции, чтобы в дальнейшем, к примеру, открыть их табличным редактором.
А теперь очень интересный скрипт.
Скрипт пишет лог об удаленных файлах.
Как оказалось при удалении файлов и удалении дескрипторов создается одно и тоже событие в логе, под При этом в теле сообщения могут быть разные значения «Операции доступа»: Запись данных (или добавление файла), DELETE и т.д.
Конечно же нас интересует операция DELETE. Но и это еще не все. Самое интересное, то что, при обычном переименовании файла создается 2 события с ID 4663, первое с Операцией доступа: DELETE, а второе с операцией: Запись данных (или добавление файла). Значит если просто отбирать 4663 то мы будем иметь очень много недостоверной информации: куда попадут файлы и удаленные и просто переименованные.
Однако мной было замечено, что при явном удалении файла создается еще одно событие с ID 4660, в котором, если внимательно изучить тело сообщения, содержится имя пользователя и еще много всякой служебной информации, но нет имени файла. Зато есть код дескриптора.

Однако предшествующим данному событию было событие с ID 4663. Где как раз таки и указывается и имя файла, и имя пользователя и время, и операция как не странно там DELETE. И самое главное там имеется номер дескриптора, который соответствует номеру дескриптора из события выше (4660, помните? которое создается при явном удалении файла). Значит теперь, чтобы точно знать какие файлы удалены, необходимо просто найти все события с ID 4660, а так же предшествующие каждому этому событию, событие с кодом 4663, в котором будет содержаться номер нужного дескриптора.

Эти 2 события генерируются одновременно при удалении файла, но записываются последовательно, сначала 4663, потом 4660. При этом их порядковые номера различаются на один. У 4660 порядковый номер на единицу больше чем у 4663.
Именно по этому свойству и ищется нужное событие. 
Т.е. берутся все события с ID 4660. У них берется 2 свойства, время создания и порядковый номер.
Далее в цикле по одному берется каждое событие 4660. Выбирается его свойства, время и порядковый номер.
Далее в переменную $PrevEvent заносится номер нужного нам события, где содержится нужная информация об удаленном файле. А так же определяются временные рамки в которых необходимо искать данное событие с определенным порядковым номером (с тем самым который мы занесли в $PrevEvent). Т.к. событие генерируется практически одновременно, то поиск сократим до 2х секунд: + — 1 секунда.
(Да, именно +1 сек и -1 сек, почему именно так, не могу сказать, было выявлено экспериментально, если не прибавлять секунду, то некоторые может не найти, возможно связано с тем, что возможно два эти события могут создаваться один раньше другой позже и наоборот).
Сразу оговорюсь, что искать только по порядковому номеру по всем событиям в течении часа — очень долго, т.к. порядковый номер находиться в теле события, и чтобы его определить, нужно пропарсить каждое событие — это очень долго. Именно поэтому необходим такой маленький период в 2 секунда (+-1сек от события 4660, помните?).
Именно в этом временном промежутке ищется событие с необходимым порядковым номером.
После того как оно найдено, работают фильтры:
Т.е. не записываем информацию об удаленных временных файлах (.*tmp), файлах блокировок документов MS Office (.*lock), и временных файлах MS Office (.*
$*)
Таким же образом берем необходимые поля из этого события, и пишем их в переменную $BodyL.
После нахождения всех событий, пишем $BodyL в текстовый файл лога.
Для лога удаленных файлов я использую схему: один файл на один месяц с именем содержащим номер месяца и год). Т.к. удаленных файлов в разы меньше чем файлов к которым был доступ.
В итоге вместо бесконечного «рытья» логов в поисках правды, можно открыть лог-файл любым табличным редактором и просмотреть нужные нам данные по пользователю или файлу.
Рекомендации
Вам придется самим определить время в течении которого вы будете искать нужные события. Чем больше период, тем дольше ищет. Все зависит от производительности сервера. Если слабенький — то начните с 10 минут. Посмотрите, как быстро отработает. Если дольше 10 минут, то либо увеличьте еще, вдруг поможет, либо наоборот уменьшите период до 5 минут.
После того как определите период времени. Поместите данный скрипт в планировщик задач и укажите, что выполнять данный скрипт необходимо каждые 5,10,60 минут (в зависимости какой период вы указали в скрипте). У меня указано каждый 60 минут. $time = (get-date) — (new-timespan -min 60).
Простая система аудита удаления файлов и папок для Windows Server
Любой администратор Windows сталкивался с ситуацией, когда разъяренные пользователи хотят узнать, кто именно удалил мега важный файл с годовым отчетом в общей папке на файловом сервере. Эту информацию можно получить только при условии ведения аудита удаления файлов и папок на файловом сервере, иначе останется только восстановить удаленный файл из резервной копии (а вы их уже делаете?) и развести руками.
Но, даже при включенном аудите удаления файлов, найти что-то в логах бывает проблематично. Во-первых, найти нужную запись среди тысячи событий довольно сложно (в Windows отсутствуют вменяемые средства поиска интересующего события с возможностью гибкой фильтрации), а во-вторых, если файл был удален давно, это событие может просто отсутствовать в журнале, т.к. было перезатерто более новыми.
В этой статье мы покажем пример организации на встроенных средствах Windows системы аудита удаления файлов и папок в общем сетевом каталоге (файловом сервере) с записью событий в отдельную базу данных на MySQL.
Благодаря наличию БД с информацией обо всех удаленных файлах администратор сможет дать ответы на вопросы:
- Кто и когда удалил файл
- Из какого приложения удален файл
- На какой момент времени нужно восстанавливать бэкап
В первую очередь на файловом сервере Windows нужно включить аудит событий, обеспечивающий запись информации об удалении файлов в журнал системы. Эту процедуру мы уже рассматривали в статье Аудит доступа к файлам и папкам в Windows.
Аудит может быть включен через общую политику Audit Object Access в разделе политик Security Settings -> Local Policy -> Audit Policy

Или (предпочтительнее) через расширенные политики аудита в GPO: Security Settings -> Advanced Audit Policy Configuration -> Object Access -> Audit File System.

В свойствах общей сетевой папки (Security -> Advanced -> Auditing), удаление файлов в котором мы хотим отслеживать, для группы Everyone включим аудит событий удаления папок и файлов (Delete subfoldersand files).

Совет. Аудит удаления файлов в конкретной папке можно включить и через PowerShell:
$Path = «D:Public»
$AuditChangesRules = New-Object System.Security.AccessControl.FileSystemAuditRule(‘Everyone’, ‘Delete,DeleteSubdirectoriesAndFiles’, ‘none’, ‘none’, ‘Success’)
$Acl = Get-Acl -Path $Path
$Acl.AddAuditRule($AuditChangesRules)
Set-Acl -Path $Path -AclObject $Acl
При успешном удалении файла в журнале безопасности системы появляется событие Event ID 4663 от источника Microsoft Windows security auditing. В описании события есть информация об имени удаленного файла, учетной записи из-под которой было выполнено удаление и имени процесса.

Итак, интересующие нас события пишутся в журнал, настала пора создать на сервере MySQL таблицу, состоящую из следующих полей:
- Имя сервера
- Имя удаленного файла
- Время удаления
- Имя пользователя, удалившего файл
MySQL запрос на создание такой таблицы будет выглядеть так:
CREATE TABLE track_del (id INT NOT NULL AUTO_INCREMENT, server VARCHAR(100), file_name VARCHAR(255), dt_time DATETIME, user_name VARCHAR(100), PRIMARY KEY (ID));
Скрипт сбора информации из журнала событий. Мы фильтруем журнал по событию с ID 4663 за текущий день

Следующий скрипт запишет полученные данные в БД MySQL на удаленном сервере:
Теперь, чтобы узнать, кто удалил файл «document1 — Copy.DOC», достаточно в консоли PowerShell выполнить следующий скрипт.
В консоли получаем имя пользователя и время удаления файла.

Скрипт сброса данных из журнала в БД можно выполнять один раз в конце дня по планировщику или повесить на событие удаления (On Event), что более ресурсоемко. Все зависит от требования к системе.
При желании по аналогии можно реагировать простую веб страницу на php для получения информации о виновниках удаления файлов в более удобном виде. Задача решается силами любого php программиста за 1-2 часа.
Итак, мы предложили идею и некий общий каркас системы аудита и хранения информации об удаленных файлах в сетевых шарах, при желании ее с лёгкостью можно будет модифицировать под ваши нужды.
Как узнать кто удалил файлы из общей папки?
После настройки аудита, найдите в журнале Security вы сможете найти с: Кто и когда удалил файл в сетевой папке; Из какого приложения удален файл; На какой момент времени нужно восстанавливать бэкап данного каталога.Nov 18, 2020
Найдите папку, в которой хранился нужный файл или папка, щелкните ее правой кнопкой мыши, а затем щелкните «Восстановить прежнюю версию». Как восстановить удаленный документ из сетевой папки?
Щелкните правой кнопкой мыши файл или папки и выберите Восстановить прежнюю версию. Вы увидите список доступных предыдущих версий файла или папки. В этот список включаются и файлы, сохраненные при резервном копировании (если вы используете программу архивации данных), и точки восстановления (если доступны оба типа архивации).
Во втором случае, когда пользователь удаляет файлы другими возможными способами (например, при помощи комбинации клавиш «Shift + Delete», или в свойствах «Корзины Windows» активирован режим уничтожения файлов сразу после удаления и т.д.), то такие файлы стираются сразу напрямую.
После настройки аудита, вы можете с помощью информации в журнале событий найти пользователя, который удалил на файловом сервере. При удалении файла из сетевой папки, он удаляется сразу, а не отправляется в корзину пользователя.
Как узнать кто использует файл?
Проводник может подсказать программу, использующую его. В Windows 7 и выше можно воспользоваться встроенной программой «Монитор ресурсов» (resmon), где на вкладке CPU есть поиск дескрипторов. Утилита NoVirus Thanks FileGovernor (описание) Утилита NirSoft OpenFilesView (работает с ограничениями на х64).
Как узнать что удаляли с компьютера?
Откройте «Панель управления» (Control Panel), найдите пункт «Администрирование» (Administrative Tools) и выберите «Управление компьютером» (Computer Management). Здесь вы увидите «Просмотр событий» (Event Viewer) в левой навигационной панели. Вот в этом пункте меню и находятся «Журналы Windows».
Как узнать кто держит папку?
Нажмите сочетание клавиш Win + R и выполните в открывшемся окошке команду resmon. Откроется окно монитора ресурсов. Переключитесь в нём на вкладку «ЦП» и введите в поле «Поиск дескрипторов» название объекта, при удалении, перемещении или переименовании которого возникла ошибка. Результаты отобразятся тут же, чуть ниже.
Как посмотреть у кого открыта папка?
Запустите на файловом сервере консоль Computer Management (или подключитесь к нему удаленно консолью со своего компьютера) и перейдите в секцию System Tools -> Shared Folders -> Open files (Служебные программы -> Общие папки -> Открыты файлы). В правой части окна отображается список файлов сервера, открытых удаленно .