Заметки · 15.08.2025

ErrorLog на связи

Продолжим про FreeFileSync и зеркалирование файлового хранилища на резервный сервер. На повестке дня снова логи с ошибками синхронизации, а точнее их доставка на электронную почту с помощью PowerShell.

За основу я взял идею из этого поста, добавив к фильтрации сегментов журнала с ошибками возможность отправлять письмо, если количество ошибок превышает нулевое значение.

# Папка с логами #
$logdir = "C:\backup_config"

# Последний созданный log-файл #
$latestlogfile = (Get-ChildItem -Path $logdir -Filter *.log | Sort-Object LastAccessTime -Descending | Select-Object -First 1).FullName

# Получение текста из файла #
$content = Get-Content -LiteralPath $latestlogfile -Encoding UTF8

# Массив для хранения ошибок #
$errors = @()

# Поиск и фильтрация сегментов #
foreach ($segment in $content -join "`n" -replace '\r\n', "\n" -split '(?=\[\d+:\d+\:\d+\])') 
{
    if ($segment -match 'Ошибка') 
    {
        $errors += $segment
    }
}

# Запись найденных ошибок в выходной файл #
if ($errors.Count -gt 0) 
{
    # IP почтового сервера #
    $mailserver = "192.168.1.2"

    # Адрес почтового ящика для приёма/отправки письма #
    $mail = "admin@domain.ru"

    # Создание сообщения #
    $message = New-Object System.Net.Mail.MailMessage $mail, $mail

    # Тема сообщения #
    $message.Subject = "Ошибки синхронизации файловой шары"

    # Тело сообщения #
    $message.Body = $errors

    # Создание клиента #
    $smtp = New-Object Net.Mail.SmtpClient($mailserver)

    # Отправка письма #
    $smtp.Send($message)
}

Каждая строка кода снабжена сопутствующим комментарием. Требуется только поменять значения переменных $logdir, $mailserver и $mail.

Скрипт можно смело скормить планировщику и ждать писем. Самое главное — не забудьте перед вызовом скрипта понизить политику безопасности выполнения скриптов PowerShell.

В моём случае действие задачи выглядит так:

<Actions Context="Author">
    <Exec>
      <Command>powershell.exe</Command>
      <Arguments>-ExecutionPolicy Bypass -NonInteractive -WindowStyle Hidden -File "путь\к\скрипту.ps1"</Arguments>
    </Exec>
  </Actions>

Как только задача отработает и все условия работы скрипта будут соблюдены — на указанный почтовый ящик (переменная $mail) упадёт письмо примерно такого содержания:

[1:00:45]
__________________________________________
|
|    Выполнено с ошибками
|
|    Ошибки: 1
|    Предупреждения: 120
|    Элементов обработано: 6 604 (4,66 ГБ)
|    Элементов осталось: 1 (41,8 КБ)
|    Общее время: 01:58:36
|_________________________________________


Ошибки и предупреждения:
________________________________________
 [2:35:00]  Ошибка:  Невозможно скопировать файл 
                    "D:\files\folder001\somefile.ext" в "\\backup-server\file-server\files\folder001\somefile.ffs_tmp".
                    ERROR_INVALID_NAME: Синтаксическая ошибка в имени файла, имени папки или метке тома. [CopyFileEx]

Очень важный момент: FreeFileSync настраивается для каждого пользователя в отдельности и если Вы уже указали формат хранения журналов в текстовом формате для пользователя admin1, то для пользователя admin2 формат хранения всё ещё будет html. Учитывайте это при автоматизации обработки журналов.

Про смену формата файла журнала я уже упоминал где-то здесь.