UncleFather » 24 мар 2014 19:42, Пн
Задача:
Имеется файл, изменения которого необходимо отслеживать. При его изменении/удалении/создании нужно выполнить какое-либо действие. Операционная система Windows 7 и выше.
Решение:
Для примера возьмем файл C:\Soft\Test\MyDoc.xls, и при изменении будем его копировать на рабочий стол компьютера в ЛВС. Например, путь куда будем копировать: \\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls
-
В Локальных политиках безопасности (secpol.msc) -> Параметры безопасности -> Локальные политики -> Политика аудита -> включаем политику Аудит доступа к объектам -> Успех:
Примечание: Здесь лучше пользоваться «Расширенной политикой аудита», которая доступна в версиях Windows начиная с Vista и выше, поскольку включение всей политики «Аудит доступа к объектам» приведет к огромному количеству ненужных записей в журнале безопасности. А «Расширенная политика аудита» позволяет настраивать аудит для конкретных событий. В данном случае нам нужно включить параметр «Доступ к объектам» -> «Аудит файловой системы». Подробнее смотрим в статье «Расширенные политики аудита».
-
В свойствах безопасности папки, в которой находится отслеживаемый файл
настраиваем политику аудита для группы ВСЕ:
-
Тип - Успех;
-
Применяется к: - Здесь указываем область, для которой нужно отслеживать доступ. Если это только один файл в папке, то нужно указать: «Только для файлов», если же требуется отслеживать все содержимое, в том числе и содержимое подпапок, то указываем: «Для этой папки, ее подпапок и файлов»;
Общие разрешения - Запись.
Можно так же добавить аудит событий удаления подпапок и файлов (это может понадобиться, например, если наблюдаемый файл будет синхронизироваться сторонним ПО типа Яндекс.Диск):
и получаем настроенный аудит для папки:
-
Создаем PowerShell скрипт и сохраняем его, например по пути C:\Soft\Bat\MyDoc.ps1:
Код: Выделить всё
$login = "UserName" #Имя пользователя для подключения сетевого диска
$pass = ConvertTo-SecureString "MyPassword" -AsPlainText -Force #Преобразуем пароль для подключения сетевого диска в защищенную строку
$creds = New-Object System.Management.Automation.PSCredential ($login, $pass) #Преобразуем учетные данные к типу PSCredential
New-PSDrive -Name MyDrv -PSProvider FileSystem -Root "\\Book01\c$\Documents and Settings\User" -Credential $creds #Подключаем сетевой ресурс \\Book01\c$\Documents and Settings\User как диск с именем MyDrv, используя полученные ранее учетные данные
Start-Sleep -s 10 #Даем спокойно закрыться файлу и записать все события в журнал
$SourceFile="C:\Soft\Test\MyDoc.xls" #Источник - файл, за которым следим
$DestFile="\\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls" #Файл, в который будем копировать (здесь можно использовать синтаксис с использованием подключенного сетевого диска, тогда путь будет таким: "MyDrv:\Рабочий стол\MyDoc.xls")
#Если за последние 30 секунд в журнале "Безопасность" возникло событие 4663, содержащее в описании имя исходного файла, то
if (Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4663;Data=$SourceFile;StartTime=(Get-Date).AddSeconds(-30)}) {
copy-item -path $SourceFile -destination $DestFile -Force #Копируем отслеживаемый файл в новое место
}
Чуть дальше, при создании триггера будет понятно, что в скрипте можно было и не фильтровать события, поскольку сам триггер у нас будет настроен именно на событие записи именно отслеживаемого файла. В принципе, из всего скрипта можно оставить только подключение сетевого диска, задержку в 10 секунд и саму операцию копирования файла. То есть можно смело вместо PowerShell использовать обычный командный файл. Но мне как-то больше приглянулся PowerShell...
А можно чуть изменить скрипт. Например, при изменении файла будем отправлять его на электронную почту:
Код: Выделить всё
$ConstServer = "smtp.server.ru" #SMTP сервер
$ConstSMTPPort = "25" #Порт SMTP сервера
$ConstFrom = "sender@server.ru" #Адрес отправителя
$ConstTo = "recepient@server.ru" #Адрес получателя
$ConstMessageTypeHTML = $false #Формат сообщения HTML (true) или обычный текст (false)
$ConstUserName = "sender@server.ru" #Имя пользователя (ящика) для авторизации на SMTP сервере
$ConstUserPass = "MyPassword" #Пароль для авторизации на SMTP сервере
$ConstMessageSubject = "Изменен файл " #Тема сообщения
$ConstMessageBody = " - изменен файл " #Тело сообщения
$SourceFile="C:\Soft\Test\MyDoc.xls" #Файл, за которым следим
Start-Sleep -s 10 #Даем спокойно закрыться файлу и записать все события в журнал
#Если за последние 30 секунд в журнале "Безопасность" возникло событие 4663, содержащее в описании имя исходного файла, то
if (Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4663;Data=$SourceFile;StartTime=(Get-Date).AddSeconds(-30)}) {
#Создаем необходимые объекты и задаем переменные, необходимые для отправки и формирования SMTP сообщения:
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$Message = New-Object System.Net.Mail.MailMessage
$SmtpClient.Host = $ConstServer
$SmtpClient.Port = $ConstSMTPPort
$Message.From = $ConstFrom
$Message.To.Add($ConstTo)
$Message.BodyEncoding = [System.Text.Encoding]::UTF8
$Message.SubjectEncoding = [System.Text.Encoding]::UTF8
$Message.IsBodyHtml = $ConstMessageTypeHTML
$Message.Subject = $ConstMessageSubject + """" + $SourceFile + """"
$SmtpClient.Credentials= New-Object System.Net.NetworkCredential($ConstUserName , $ConstUserPass)
$Message.Attachments.Add($SourceFile)
$Message.Body = (get-date).ToString() + $ConstMessageBody + """" + $SourceFile + """"
$SmtpClient.Send($Message) #Отправляем SMTP сообщение
$Message.Dispose() #Отправляем сообщение QUIT на SMTP-сервер (правильно завершаем TCP-подключение и освобождаем все ресурсы, используемые текущим экземпляром класса SmtpClient)
}
-
В планировщике заданий создаем новую задачу:
-
На вкладке «Общие» настраиваем параметры: Скрытая задача, Для всех пользователей, Выполнять с наивысшими правами:
-
На вкладке «Триггеры» создаем триггер для этой задачи. В свойствах нового триггера указываем: Начинать задачу «При событии», в параметрах выбираем «Настраиваемое» и нажимаем «Создать фильтр события»:
В свойствах фильтра события переходим на вкладку «XML», ставим галочку «изменить запрос вручную» и копируем содержимое запроса:
Код: Выделить всё
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
((*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (Level=4 or Level=0) and Task = 12800 and (band(Keywords,9007199254740992)) and (EventID=4663)]]) and (*[EventData[Data[@Name="ObjectName"] and (Data='c:\soft\Test\MyDoc.xls')]]))
</Select>
</Query>
</QueryList>
Здесь c:\soft\Test\MyDoc.xls - полный путь до контролируемого файла.
Этот триггер отбирает все события из журнала «Безопасность» с Уровнем - Сведения, Источником - Microsoft Windows Security Auditing, Кодом - 4663, Категорией - Файловая система, Ключевым словом - Аудит успеха, у которых в данных самого события есть запись с именем «ObjectName», значение которой равно нашему контролируемому файлу c:\soft\Test\MyDoc.xls.
По-сути, мы фильтруем все события записи, относящиеся к искомому файлу.
В итоге получаем триггер с пользовательским фильтром событий:
-
На вкладке «Действия» создаем новую задачу с параметрами: Действие - Запуск программы, Программа или сценарий - C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, Добавить аргументы - -WindowStyle Hidden C:\Soft\Bat\MyDoc.ps1:
То есть мы запускаем оболочку PowerShell, с параметром -WindowStyle Hidden (что означает - в скрытом режиме) и выполняем написанный нами ранее PowerShell скрипт C:\Soft\Bat\MyDoc.ps1
-
На вкладке «Условия» снимаем все галочки, поскольку задача должна запускаться вне зависимости от условий питания и простоя:
-
И последняя вкладка «Параметры». Ставим галочки: Выполнять задачу по требованию, Принудительная остановка задачи, если она не прекращается по запросу, параметр «Останавливать задачу, выполняемую дольше» настраиваем на минимальное время, а параметру «Если задача уже выполняется, то применять правило» назначаем значение «Не запускать новый экземпляр»:
Теперь, после изменения файла C:\Soft\Test\MyDoc.xls он будет копироваться в \\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls
Дополнение: в принципе, этот метод можно адаптировать и под Windows XP, но, честно говоря, эта ОС уходит в прошлое и уже просто не хочется тратить время. Тем не менее, если кому понадобится, то даю наводки - из журнала событий берем события 560 и 567 и совместно их анализируем - в 560-м имя файла, в 567-м - метод (чтение или запись). Для запроса событий журнала из PowerShell используем командлет Get-EventLog, будет запрос типа такого:
Код: Выделить всё
Get-EventLog -LogName Security -EntryType SuccessAudit -InstanceId 560 -Message *C:\Soft\Temp* -Newest 1 -Source Security
Сохраняем полученный скрипт в папке, например «c:\Soft\Bat\WriteFileAudit.ps1», ну и создаем триггер на событие 560 журнала Security так, как описано здесь, получится что-то подобное:
Код: Выделить всё
eventtriggers /create /TR "Write File" /TK "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden c:\Soft\Bat\WriteFileAudit.ps1" /L Security /EID 560
[b][size=150]Задача:[/size][/b]
Имеется файл, изменения которого необходимо отслеживать. При его изменении/удалении/создании нужно выполнить какое-либо действие. Операционная система Windows 7 и выше.
[b][size=150]Решение:[/size][/b]
Для примера возьмем файл [b][i]C:\Soft\Test\MyDoc.xls[/i][/b], и при изменении будем его копировать на рабочий стол компьютера в ЛВС. Например, путь куда будем копировать: [b][i]\\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls[/i][/b]
[list=1][*] В [b][i]Локальных политиках безопасности (secpol.msc) -> Параметры безопасности -> Локальные политики -> Политика аудита ->[/i][/b] включаем политику [b][i]Аудит доступа к объектам -> Успех[/i][/b]:[spoiler title=Включение аудита:][attachment=11]01.jpg[/attachment][/spoiler]
[b][size=120][color=#BF8000]Примечание[/color]:[/size][/b] Здесь лучше пользоваться «[b][i]Расширенной политикой аудита[/i][/b]», которая доступна в версиях [b][i]Windows[/i][/b] начиная с [b][i]Vista[/i][/b] и выше, поскольку включение всей политики «[b][i]Аудит доступа к объектам[/i][/b]» приведет к огромному количеству ненужных записей в журнале безопасности. А «[b][i]Расширенная политика аудита[/i][/b]» позволяет настраивать аудит для конкретных событий. В данном случае нам нужно включить параметр «[b][i]Доступ к объектам[/i][/b]» -> «[b][i]Аудит файловой системы[/i][/b]». Подробнее смотрим в статье «[url=http://manaeff.ru/forum/viewtopic.php?p=1639#p1639]Расширенные политики аудита[/url]».
[*] В свойствах безопасности папки, в которой находится отслеживаемый файл
[spoiler title=Безопасность папки:][attachment=10]02.jpg[/attachment][/spoiler]
настраиваем политику аудита для группы [b][i]ВСЕ[/i][/b]:
[list][*] [b][i]Тип[/i][/b] - Успех; [*] [b][i]Применяется к[/i][/b]: - Здесь указываем область, для которой нужно отслеживать доступ. Если это только один файл в папке, то нужно указать: «[b][i]Только для файлов[/i][/b]», если же требуется отслеживать все содержимое, в том числе и содержимое подпапок, то указываем: «[b][i]Для этой папки, ее подпапок и файлов[/i][/b]»; [*][b][i]Общие разрешения[/i][/b] - Запись.[/list][spoiler title=Настраиваем аудит:][attachment=9]03.jpg[/attachment][/spoiler]
Можно так же добавить аудит событий удаления подпапок и файлов (это может понадобиться, например, если наблюдаемый файл будет синхронизироваться сторонним ПО типа Яндекс.Диск):
[spoiler title=Аудит с удалением:][attachment=0]13.jpg[/attachment][/spoiler]
и получаем настроенный аудит для папки:
[spoiler title=Настроенный аудит папки:][attachment=8]04.jpg[/attachment][/spoiler]
[*] Создаем PowerShell скрипт и сохраняем его, например по пути [b][i]C:\Soft\Bat\MyDoc.ps1[/i][/b]:[spoiler title=Код сценария PowerShell][code]
$login = "UserName" #Имя пользователя для подключения сетевого диска
$pass = ConvertTo-SecureString "MyPassword" -AsPlainText -Force #Преобразуем пароль для подключения сетевого диска в защищенную строку
$creds = New-Object System.Management.Automation.PSCredential ($login, $pass) #Преобразуем учетные данные к типу PSCredential
New-PSDrive -Name MyDrv -PSProvider FileSystem -Root "\\Book01\c$\Documents and Settings\User" -Credential $creds #Подключаем сетевой ресурс \\Book01\c$\Documents and Settings\User как диск с именем MyDrv, используя полученные ранее учетные данные
Start-Sleep -s 10 #Даем спокойно закрыться файлу и записать все события в журнал
$SourceFile="C:\Soft\Test\MyDoc.xls" #Источник - файл, за которым следим
$DestFile="\\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls" #Файл, в который будем копировать (здесь можно использовать синтаксис с использованием подключенного сетевого диска, тогда путь будет таким: "MyDrv:\Рабочий стол\MyDoc.xls")
#Если за последние 30 секунд в журнале "Безопасность" возникло событие 4663, содержащее в описании имя исходного файла, то
if (Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4663;Data=$SourceFile;StartTime=(Get-Date).AddSeconds(-30)}) {
copy-item -path $SourceFile -destination $DestFile -Force #Копируем отслеживаемый файл в новое место
}[/code][/spoiler]
Чуть дальше, при создании триггера будет понятно, что в скрипте можно было и не фильтровать события, поскольку сам триггер у нас будет настроен именно на событие записи именно отслеживаемого файла. В принципе, из всего скрипта можно оставить только подключение сетевого диска, задержку в 10 секунд и саму операцию копирования файла. То есть можно смело вместо PowerShell использовать обычный командный файл. Но мне как-то больше приглянулся PowerShell... :)
А можно чуть изменить скрипт. Например, при изменении файла будем отправлять его на электронную почту:
[spoiler title=Измененный код PowerShell:][code]$ConstServer = "smtp.server.ru" #SMTP сервер
$ConstSMTPPort = "25" #Порт SMTP сервера
$ConstFrom = "sender@server.ru" #Адрес отправителя
$ConstTo = "recepient@server.ru" #Адрес получателя
$ConstMessageTypeHTML = $false #Формат сообщения HTML (true) или обычный текст (false)
$ConstUserName = "sender@server.ru" #Имя пользователя (ящика) для авторизации на SMTP сервере
$ConstUserPass = "MyPassword" #Пароль для авторизации на SMTP сервере
$ConstMessageSubject = "Изменен файл " #Тема сообщения
$ConstMessageBody = " - изменен файл " #Тело сообщения
$SourceFile="C:\Soft\Test\MyDoc.xls" #Файл, за которым следим
Start-Sleep -s 10 #Даем спокойно закрыться файлу и записать все события в журнал
#Если за последние 30 секунд в журнале "Безопасность" возникло событие 4663, содержащее в описании имя исходного файла, то
if (Get-WinEvent -maxevents 1 -FilterHashtable @{LogName=”Security”;ID=4663;Data=$SourceFile;StartTime=(Get-Date).AddSeconds(-30)}) {
#Создаем необходимые объекты и задаем переменные, необходимые для отправки и формирования SMTP сообщения:
$SmtpClient = New-Object System.Net.Mail.SmtpClient
$Message = New-Object System.Net.Mail.MailMessage
$SmtpClient.Host = $ConstServer
$SmtpClient.Port = $ConstSMTPPort
$Message.From = $ConstFrom
$Message.To.Add($ConstTo)
$Message.BodyEncoding = [System.Text.Encoding]::UTF8
$Message.SubjectEncoding = [System.Text.Encoding]::UTF8
$Message.IsBodyHtml = $ConstMessageTypeHTML
$Message.Subject = $ConstMessageSubject + """" + $SourceFile + """"
$SmtpClient.Credentials= New-Object System.Net.NetworkCredential($ConstUserName , $ConstUserPass)
$Message.Attachments.Add($SourceFile)
$Message.Body = (get-date).ToString() + $ConstMessageBody + """" + $SourceFile + """"
$SmtpClient.Send($Message) #Отправляем SMTP сообщение
$Message.Dispose() #Отправляем сообщение QUIT на SMTP-сервер (правильно завершаем TCP-подключение и освобождаем все ресурсы, используемые текущим экземпляром класса SmtpClient)
}[/code][/spoiler]
[*] В планировщике заданий создаем новую задачу:
[list=1][*] На вкладке «[b][i]Общие[/i][/b]» настраиваем параметры: [b][i]Скрытая задача[/i][/b], [b][i]Для всех пользователей, Выполнять с наивысшими правами[/i][/b]:[spoiler title=Вкладка «Общие»:][attachment=7]05.jpg[/attachment][/spoiler]
[*] На вкладке «Триггеры» создаем триггер для этой задачи. В свойствах нового триггера указываем: [b]Начинать задачу[/b] «[b][i]При событии[/i][/b]», в параметрах выбираем «[b][i]Настраиваемое[/i][/b]» и нажимаем «[b][i]Создать фильтр события[/i][/b]»:[spoiler title=Настройка триггера:][attachment=6]08.jpg[/attachment][/spoiler]
В свойствах фильтра события переходим на вкладку «[b][i]XML[/i][/b]», ставим галочку «изменить запрос вручную» и копируем содержимое запроса:[spoiler title=Свойства фильтра события:][attachment=5]09.jpg[/attachment][/spoiler]
[spoiler title=Код XML запроса:][code]<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
((*[System[Provider[@Name='Microsoft-Windows-Security-Auditing'] and (Level=4 or Level=0) and Task = 12800 and (band(Keywords,9007199254740992)) and (EventID=4663)]]) and (*[EventData[Data[@Name="ObjectName"] and (Data='c:\soft\Test\MyDoc.xls')]]))
</Select>
</Query>
</QueryList>[/code][/spoiler]
Здесь [b][i]c:\soft\Test\MyDoc.xls[/i][/b] - полный путь до контролируемого файла.
Этот триггер отбирает все события из журнала [b][i]«Безопасность» с Уровнем - Сведения, Источником - Microsoft Windows Security Auditing, Кодом - 4663, Категорией - Файловая система, Ключевым словом - Аудит успеха[/i][/b], у которых в данных самого события есть запись с именем «[b][i]ObjectName[/i][/b]», значение которой равно нашему контролируемому файлу [b][i]c:\soft\Test\MyDoc.xls[/i][/b].
По-сути, мы фильтруем все события записи, относящиеся к искомому файлу.
В итоге получаем триггер с пользовательским фильтром событий:[spoiler title=Получившийся триггер][attachment=4]06.jpg[/attachment][/spoiler]
[*] На вкладке «[b][i]Действия[/i][/b]» создаем новую задачу с параметрами: [b][i]Действие - Запуск программы, Программа или сценарий - C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, Добавить аргументы - -WindowStyle Hidden C:\Soft\Bat\MyDoc.ps1[/i][/b]:
[spoiler title=Новая задача:][attachment=3]10.jpg[/attachment][/spoiler]
То есть мы запускаем оболочку PowerShell, с параметром [b][i]-WindowStyle Hidden[/i][/b] (что означает - в скрытом режиме) и выполняем написанный нами ранее PowerShell скрипт [b][i]C:\Soft\Bat\MyDoc.ps1[/i][/b]
[*] На вкладке «[b][i]Условия[/i][/b]» снимаем все галочки, поскольку задача должна запускаться вне зависимости от условий питания и простоя:
[spoiler title=Условия:][attachment=2]11.jpg[/attachment][/spoiler]
[*] И последняя вкладка «Параметры». Ставим галочки: [b][i]Выполнять задачу по требованию, Принудительная остановка задачи, если она не прекращается по запросу[/i][/b], параметр «[b][i]Останавливать задачу, выполняемую дольше[/i][/b]» настраиваем на минимальное время, а параметру «[b][i]Если задача уже выполняется, то применять правило[/i][/b]» назначаем значение «[b][i]Не запускать новый экземпляр[/i][/b]»:[spoiler title=Параметры:][attachment=1]12.jpg[/attachment][/spoiler][/list][/list]
Теперь, после изменения файла [b][i]C:\Soft\Test\MyDoc.xls[/i][/b] он будет копироваться в [b][i]\\Book01\c$\Documents and Settings\User\Рабочий стол\MyDoc.xls[/i][/b]
[b][size=130]Дополнение:[/size][/b] в принципе, этот метод можно адаптировать и под Windows XP, но, честно говоря, эта ОС уходит в прошлое и уже просто не хочется тратить время. Тем не менее, если кому понадобится, то даю наводки - из журнала событий берем события 560 и 567 и совместно их анализируем - в 560-м имя файла, в 567-м - метод (чтение или запись). Для запроса событий журнала из PowerShell используем командлет Get-EventLog, будет запрос типа такого:
[code]Get-EventLog -LogName Security -EntryType SuccessAudit -InstanceId 560 -Message *C:\Soft\Temp* -Newest 1 -Source Security[/code]
Сохраняем полученный скрипт в папке, например [b][i]«c:\Soft\Bat\WriteFileAudit.ps1»[/i][/b], ну и создаем триггер на событие 560 журнала Security так, как описано [url=http://manaeff.ru/forum/viewtopic.php?p=1195#p1195]здесь[/url], получится что-то подобное:
[code]eventtriggers /create /TR "Write File" /TK "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -WindowStyle Hidden c:\Soft\Bat\WriteFileAudit.ps1" /L Security /EID 560[/code]