Не самая частая задача на устройствах MikroTik — одномоментное создание большого количества PPP (англ. Point-to—Point Protocol) пользователей. Но когда она возникает, это превращается в очень скучное и нудное дело, что следует исправить.
Предыдущую статью «MikroTik Скрипт: Уведомление о успешном входе на устройство или простой парсер журнала MikroTik» добавило в закладки в закладки 80+ пользователей, надеюсь и эта статья будет не менее полезна.
— Что, мой мальчик, получается ли тебе собрать слово «Вечность»?
— Трудно, моя госпожа, сложить слово «Вечность» из букв «Ж», «П», «О» и «А» — ответил Кай.
Скриптовый язык MikroTik никак нельзя назвать полноценным языком программирования, поэтому слово «Вечность» будем собирать из того что есть, добавляя костыли и перематывая синей изолентой (ведь нет ничего долговечней, чем …).
Скрипт рассчитан на внимательных пользователей (регистр имени файла, структура файла) и не рассчитан на любознательных пользователей вида «что будет, если вместо IP адреса поставить деление на ноль?». «Защита от дурака» отсутствует, чтобы искусственно не раздувать размер скрипта.

Планируемая последовательность действий
-
Скачиваем шаблон CSV файла (FileTemplate.zip на GitHub);
-
Заполняем шаблон (проверено Microsoft Excel);
-
Загружаем файл на устройство MikroTik;
-
Создаем скрипт импорта PPP пользователей;
-
Включаем Безопасный режим MikroTik;
-
Запускаем скрипт;
-
Смотрим лог и список PPP пользователей;
-
Убедившись, что все прошло хорошо — выключаем Безопасный режим MikroTik;
-
Пишем в комментарий к статье, что всё прошло хорошо (неплохо указать модель устройства, версию RouterOS).

Создание файла
Настоятельно рекомендую использовать шаблон файла с GitHub (в этом случае пропустите этот раздел).
Но вы конечно можете создавать свой файл с любым расширением (в этом случае настраивайте :set Content [:pick $Content 62 $ContentLen]; вместо 62 выставляя свое значение от начала последовательности, в скрипте «отрезается» 62 символа — с учетом «шапки» таблицы в шаблоне).
Как разделитель элементов используется символ «;», но вы можете указать свой символ.
Как разделитель строк используется символ «\r», поэтому шаблон предоставлен в .zip формате с сохранением всех символов, т.к. множество редакторов, в том числе на GitHub отрезают «лишние» по их мнению символы.
Логика скрипта
Укажите в строке :local FileName "FileTemplate.csv"; название импортированного файла (рекомендую скопировать полное название из списка Files);
Проверка, что размер файла не превышен, запись в журнал устройства при превышении размера и остановка скрипта. Для RouterOS6 существует ограничение на размер переменной в 4КБ (у меня это было 80 пользователей, в RouterOS7 вроде как обещают снять ограничения);
«Разбираем» файл, разбивая его на строки и запуская деление на элементы в каждой строке;
Значение найденного элемента присваиваем соответствующему ключу массива ColumnsArray;
Закончив разбор строки, формируем команду MikroTik для создания PPP пользователя;
Если имя пользователя уже существует — пропускаем создание пользователя (вы можете самостоятельно добавить удаление пользователя, если требуется массовое пересоздание пользователей);
Добавляем каждое из значений массива ColumnsArray в текст команды, если значение отсутствует, попускаем.
Выполняем сформированную команду создания пользователя;
Переходим к разбору следующей строки, если индекс последнего элемента строки меньше общего количества элементов в файле.
Создать скрипт
Для запуска скрипта необходимы разрешения: read, write, test, policy.
[System] -> [Scripts] -> [+] -> [Name: CreatePPPUsers] -> [Policy: read, write, test, policy]
Внимание: излишние права (выставляются по умолчанию новому скрипту) могут привести к появлению ошибки «could not run script ParseLogAccountEvents: not enough permissions» (RouterOS 6.48), устанавливайте только указанные в статье права.
Код скрипта
# Name: CreatePPPUsers v1 # Description: Bulk create VPN users from a file # Author: Yun Sergey, MHelp.pro 2020 # License: GPL-3.0 License # Description, purpose and questions: https://mhelp.pro/mikrotik-script-bulk-create-vpn-users-from-a-file/ # More scripts Mikrotik: https://mhelp.pro/tag/mikrotik/ :local FileName "FileTemplate.csv"; :log warning "Script CreatePPPUsers: running. Import from file: $FileName"; :if ([/file get $FileName size] > 4096) do={ :log error "Error run script CreatePPPUsers: file size exceeded 4 KB (size constraint of a variable in Router OS 6). Split the file $FileName into several parts."; :error "File size exceeded 4 KB. Stop script." }; :local Content [/file get $FileName contents]; :local ContentLen [:len $Content]; :set Content [:pick $Content 62 $ContentLen]; :local StartCursor 0; :local EndCursor; :local LineEndCursor; :while ($StartCursor < [:len $Content]) do={ :set LineEndCursor [:find $Content "\r" $StartCursor]; :local Cont; :local ColumnsArray { "01Name"="" ; "02Password"="" ; "03Service"="" ; "04Profile"="" ; "05LocalAdress"="" ; "06RemoveAddress"=""}; # START PARSING STRING :foreach Key,Value in=$ColumnsArray do={ :local Symbol [:pick $Content $StartCursor]; :if ($Symbol =";") do={:set StartCursor ($StartCursor - 1)}; :set EndCursor [:find $Content ";" $StartCursor]; :if (($EndCursor > $LineEndCursor) or ([:typeof $EndCursor]="nil")) do={:set EndCursor [:find $Content "\r" ($StartCursor-1)];}; :set Cont [:pick $Content $StartCursor $EndCursor]; :set ($ColumnsArray -> $Key ) $Cont; :set StartCursor ($EndCursor+1); }; # END PARSING STRING # START CREATE COMMAND :local UserName ($ColumnsArray -> "01Name"); :if ([/ppp secret find name=$UserName ]) do={ :log info "Add PPP user: $UserName - already exist! Skipped."; } else={ :local Command "/ppp secret add name=$UserName"; :local UserPassword ($ColumnsArray -> "02Password"); :if ($UserPassword != ";") do= {:set Command ("$Command" . " password=$UserPassword")}; :local UserService ($ColumnsArray -> "03Service"); :if ($UserService != ";") do= {:set Command ("$Command" . " service=$UserService")}; :local UserProfile ($ColumnsArray -> "04Profile"); :if ($UserProfile != ";") do= {:set Command ("$Command" . " profile=$UserProfile")}; :local UserLocalAdress ($ColumnsArray -> "05LocalAdress"); :if ($UserLocalAdress != ";") do= {:set Command ("$Command" . " local-address=$UserLocalAdress")}; :local UserRemoveAddress ($ColumnsArray -> "06RemoveAddress"); :if ($UserRemoveAddress != ";") do= {:set Command ("$Command" . " remote-address=$UserRemoveAddress")}; [:parse $Command]; }; # END CREATE COMMAND :set StartCursor ($EndCursor+2); }; :delay 2; :log warning "Script CreatePPPUsers: completed.";
Скрипт намеренно сделан в упрощенном виде, избегая вложенных конструкций, затрудняющих чтение кода, но никто не мешает вам «дооптимизировать» скрипт в «одну» или минимальное количество строк.
Если вам интересны другие мои скрипты MikroTik, их можно увидеть здесь или на GitHub.
Если вы использовали скрипт, оставьте пожалуйста обратную связь «Работает. Модель устройства и версия RouterOS». Это поможет другим. Спасибо.
Проверено: MikroTik hAP ac lite (RouterBOARD 952Ui-5ac2nD), RouterOS 6.47.8 (stable).
ссылка на оригинал статьи https://habr.com/ru/post/532696/
Добавить комментарий