Снова навеяно темой на форуме TechNet-Ru. Уже не первый раз встречаю топики про архивирование журналов событий для последующего хранения в оффлайне. Безусловно не стоит пытаться скопировать .evt файл из папки Windows, поскольку файлы открыты и заблокированы (как и .pst файлы при запущенном MS Outlook). Для архивирования журнала скриптом нужно либо использовать Volume Shadow Copy либо использовать особые методы (например, вот так: http://support.microsoft.com/kb/312571). В качестве особых методов можно так же выделить использование WMI, которое позволяет решить поставленную задачу и добавит нам удалённой управляемости.
Полностью опираться на тему форума нельзя, ибо задача поставлена некорректно. Смысла в ежедневном удалении логов с машин без предварительного архивирования нету совсем (иначе вы потеряете точку отправления в решении проблемы, когда она возникнет и зачастую единственным выходом будет переинсталляция или восстановление из бакупа). Поэтому немного переформулируем задачу и напишем решение.
Задача: проводить с некоторой периодичностью архивацию журнала событий в файл. Убедиться, что бэкап сделан и после этого очистить журналы. В противном случае сделать что-нибудь другое.
За отправную точку возьмём класс Win32_NTEventlogFile. Давайте, вызовем его:
[vPodans] gwmi Win32_NTEventlogFile FileSize LogfileName Name -------- ----------- ---- 8458240 Application C:\Windows\System32\Winevt... 69632 DFS Replication C:\Windows\System32\Winevt... 69632 HardwareEvents C:\Windows\System32\Winevt... 69632 Internet Explorer C:\Windows\System32\Winevt... 69632 Key Management Service C:\Windows\System32\Winevt... 69632 ODiag C:\Windows\System32\Winevt... 1118208 OSession C:\Windows\System32\Winevt... 20975616 System C:\Windows\System32\Winevt... 11603968 Windows PowerShell C:\Windows\System32\Winevt... [vPodans]
Он показал список доступных журналов, с которыми мы можем работать. Давайте взглянем на методы данного класса:
[vPodans] gwmi Win32_NTEventlogFile | gm -MemberType method TypeName: System.Management.ManagementObject#root\cimv2\Win32_NTEventlogFile Name MemberType Definition ---- ---------- ---------- BackupEventlog Method System.Management.ManagementBaseObject BackupEventlog(System.String ArchiveFi... ChangeSecurityPermissions Method System.Management.ManagementBaseObject ChangeSecurityPermissions(System.Manag... ChangeSecurityPermissionsEx Method System.Management.ManagementBaseObject ChangeSecurityPermissionsEx(System.Man... ClearEventlog Method System.Management.ManagementBaseObject ClearEventlog(System.String ArchiveFil... Compress Method System.Management.ManagementBaseObject Compress() CompressEx Method System.Management.ManagementBaseObject CompressEx(System.String StartFileName... Copy Method System.Management.ManagementBaseObject Copy(System.String FileName) CopyEx Method System.Management.ManagementBaseObject CopyEx(System.String FileName, System.... DeleteEx Method System.Management.ManagementBaseObject DeleteEx(System.String StartFileName) GetEffectivePermission Method System.Management.ManagementBaseObject GetEffectivePermission(System.UInt32 P... Rename Method System.Management.ManagementBaseObject Rename(System.String FileName) TakeOwnerShip Method System.Management.ManagementBaseObject TakeOwnerShip() TakeOwnerShipEx Method System.Management.ManagementBaseObject TakeOwnerShipEx(System.String StartFil... Uncompress Method System.Management.ManagementBaseObject Uncompress() UncompressEx Method System.Management.ManagementBaseObject UncompressEx(System.String StartFileNa... [vPodans]
Здесь нас заинтересует 2 метода - BackupEventlog и ClearEventlog (там ещё есть ChangeSecurityPermissions - я бы не советовал с ним связываться :-D). В упрощённом варианте копирование и удаление будет сводиться к:
$LogName = "Application" $Eventlog = gwmi Win32_NTEventlogFile -Filter "LogFileName = '$LogName'" $Eventlog.BackupEventLog("F:\Eventlogs\$env:computername\$LogName" + "_" + "$(Get-Date -Format dd.MM.yyyy).evt") $EventLog.Clear()
В данном случае с локальной машины заархивируем журнал Application в путь (после преобразований переменных) F:\Eventlogs\THOR\Application_04.12.2008.evt, после чего данный журнал будет очищен. Ничего сложного нету совсем. Разве что кроме одной детали. Такой фокус не получится с журналом Security, поскольку это жрунал аудита. И для очистки журнала потребуется право Manage auditing and security log привилегия SeAudit (в общем смысле это будет административная учётная запись). Поэтому перед использованием метода ClearEventlog нужно подключить эти самые привилегии:
$EventLog.PSBase.Scope.Options.EnablePrivileges = $true
вот и всё. Осталось только решить задачу ротации журналов (удалять все файлы, которые старше 365 дней или 1 года):
dir F:\Eventlogs\$env:computername -Recurse | ? {$_.lastwritetime -gt (Get-Date).AddDays(-365)} | del -Force
В качестве последнего штриха стоит оформить всё в красивый скрипт:
######################################################## # EventLog Backup Manager.ps1 # Version 1.0 # # Eventlog archiving script # # Vadims Podans (c) 2008 # http://www.sysadmins.lv/ ######################################################## function Backup-Eventlog { param ([string]$Computer) Begin { # разово получаем текущую дату в простом формате для пристыковки даты к имени файла $date = Get-Date -Format dd.MM.yyyy } Process { # получение списка всех журналов событий на текущем компьютере $Eventlog = gwmi Win32_NTEventlogFile -ComputerName $Computer $Eventlog | % { # косметическая переменная для вставки имени лога в текстовые сообщения $CurrentName = $_.LogFileName $CurrentLog = $_ # включение SeAudit привилегий $_.PSBase.Scope.Options.EnablePrivileges = $true # задаём путь, куда будут складываться архивы эвентлога $path = "\\BackupServer\Eventlogs\$computer\$CurrentName" + "_" + $date + ".evt" Write-Host "Processing $CurrentName log on $computer .." # непосредственно сам бэкап $Backup = $_.BackupEventLog($path) # проверка статуса бэкапа текущего журнала if ($Backup.ReturnValue -eq 0) { Write-Host "Success" # если бэкап прошёл успешно, то можно удалять записи в журнале и командлетом Out-Null# подавляем ненужный вывод на экран $CurrentLog.ClearEventlog() | out-null } else { Write-Warning "Unexpected error occured. Operation aborted" } } } End { # эта часть обеспечивает удаление старых архивов и их ротацию после каждого запуска скрипта # стоит отметить, что данная секция выполняется только один раз и после проведения всей архивации Write-Host "Purging old archives .." dir \\BackupServer\Eventlogs\$computer -Recurse | ? {$_.lastwritetime -gt (Get-Date).AddDays(-365)} | del -Force } }
как бы и всё.
Проблемка Windows 2008 PS C:\Users\Administrator> gwmi Win32_NTEventlogFile FileSize LogfileName Name -------- ----------- ---- 20975616 Application C:\Windows\System32\Winevt... 69632 HardwareEvents C:\Windows\System32\Winevt... 69632 Internet Explorer C:\Windows\System32\Winevt... 1118208 Kaspersky Event Log C:\Windows\System32\Winevt... 69632 Key Management Service C:\Windows\System32\Winevt... 8458240 Operations Manager C:\Windows\System32\Winevt... 20975616 System C:\Windows\System32\Winevt... 69632 Windows PowerShell C:\Windows\System32\Winevt... А куда делся Security лог? Стандартный Event viewer его видит, а тут то почему нет?
Не могу сказать куда. У меня вроде везде Security есть.
UAC виновен. Если его отключить или запустить консоль PowerShell в режиме администратора - в списке появляется и Security но отключать не хочется, равно как и запускать PowerShell в режиме администратора. что делать то :)
ну, вы сами подметили, что у вас выбор невелик. Это как про чемодан без ручки — и нести тяжело и бросить жалко. Где-то придётся сделать выбор.
как то скриптом повысить привилегии нельзя?
можно. Но всё равно придётся нажать кнопку UAC'а или воодить пароль.
напридумывали UAC'и всякие... вообщем обошел это дело. поскольку похожий по смыслу скрипт все равно планировалось запускать через Task Scheduller - просто в настройках задачи поставил галочку "run with highest privileges"
UAC достаточно хорошая и полезная штука. Просто нужно понимать её смысл и применять с умом.
Спасибо. Очень помог твой скрипт.
Comments: