blog by ficti0n

среда, 7 сентября 2022 г.

ГитХаб

 Времени вести страничку почти нет. Если будет что то новое, буду выкладывать на ГитХаб https://github.com/volkiam

вторник, 30 июня 2020 г.

Создание заявок в системе GLPI с помощью REST API на Delphi

Для работы понадобилось провести в разрабатываемую программу интеграцию с системой хелпдеска GLPI. Поиск в интернете примеров на Delphi не принес приемлемых результатов и пришлось все писать с нуля. Вот решил поделиться примером создания заявки с прикреплением файла.
P.S. также рекомендую к прочтению вот эту статью, в ней описано GLPI  настраивать для включения REST API

Глобальные переменные и константы:

const
  AppToken = 'hAQiq39NeHWaQ25t6cTkV8762VcHL2Tds7qBuLR4';
  userToken = 'pRHHulWPKXqSrL3xS8vlSCqGIsOu7HWb7rJ3ixI4';

var
  session_token : string;
  GlpiUser, GlpiPassword, GlpiRestUrl : string;

Начинаем все с подключения к GLPI и получения токена сессии:

Function Get_session_token : string;
    var
      IdHTTP: TIdHTTP;
      Answer: string;
      JSON : TJSONObject;
begin
  try

    try
      IdHTTP := TIdHTTP.Create(nil);
      try
        IdHTTP.Request.Connection := 'Keep-Alive';
        Idhttp.HTTPOptions := [hoKeepOrigProtocol,hoForceEncodeParams,hoNoProtocolErrorException,hoWantProtocolErrorContent];
        IdHTTP.Request.ContentType := 'application/json';
        idHttp.Request.BasicAuthentication := true;
        idHttp.Request.Username := GlpiUser;
        idHttp.Request.Password := GlpiPassword;
        IdHTTP.Request.ContentEncoding := 'utf-8';
        IdHTTP.Request.CustomHeaders.Values['Authorization'] :=  'user_token  ' + userToken;
        IdHTTP.Request.CustomHeaders.Values['App-Token'] :=  AppToken;

        Answer := IdHTTP.Get(GlpiRestUrl + '/initSession/');
        JSON := TJSONObject.ParseJSONValue(Answer) as TJSONObject;
        Result := JSON.Get('session_token').JsonValue.Value;

      finally
        IdHTTP.Free;
      end;
    finally

    end;

  except
    on E: Exception do
      ShowMessage('Error: '+E.ToString);
  end;

end;

Также нам понадобиться функция для закрытия сессии:

Function KillSession (sToken: string) : boolean;
    var
      IdHTTP: TIdHTTP;
      Answer: string;
begin
  if sToken = '' then Exit;
  try
    try
      IdHTTP := TIdHTTP.Create(nil);
      try
        IdHTTP.Request.Connection := 'Keep-Alive';
        IdHTTP.Request.ContentType := 'application/json';
        idHttp.Request.BasicAuthentication := true;
        idHttp.Request.Username := GlpiUser;
        idHttp.Request.Password := GlpiPassword;
        IdHTTP.Request.ContentEncoding := 'utf-8';
        IdHTTP.Request.CustomHeaders.Values['Session-Token'] := sToken ;
        IdHTTP.Request.CustomHeaders.Values['App-Token'] :=  AppToken;

        Answer := IdHTTP.Get(GlpiRestUrl + '/killSession/');

        if IdHttp.ResponseCode = 200 then Result := true
                                     else Result := false;

      finally
        IdHTTP.Free;
      end;
    finally

    end;

  except
    on E: Exception do
      ShowMessage('Error: '+E.ToString);
  end;

end;

Ну и сама функция создания заявки с прикреплением файла:

Function CreateTiket (sToken : string): string;
    var
      IdHTTP: TIdHTTP;
      Answer: string;
      JSON, JSON2, JSON3 : TJSONObject;
      JsonToSend: TMemoryStream;
      jsontext : string;
      doc_id, doc_prefix, doc_file : string;
      MultiData : TIdMultiPartFormDataStream;
      JSONArray : TJSONArray;
      newticket_id : string;
begin
  try

    try

     IdHTTP := TIdHTTP.Create(nil);
      try
        IdHTTP.Request.Connection := 'Keep-Alive';
        IdHTTP.Request.ContentType := 'multipart/form-data';     // Это для загрузки документов
        idHttp.Request.BasicAuthentication := true;
        idHttp.Request.Username := GlpiUser;
        idHttp.Request.Password := GlpiPassword;
        Idhttp.Request.AcceptEncoding := 'gzip, identity;q=0';
        IdHttp.Compressor := TIdCompressorZLib.Create(IdHttp);
        Idhttp.Request.Accept := 'application/json';
        Idhttp.HTTPOptions := [hoKeepOrigProtocol,hoForceEncodeParams,hoNoProtocolErrorException,hoWantProtocolErrorContent];
        IdHTTP.Request.ContentEncoding := 'utf-8';
        //Параметр user_token берётся из Ключ удалённого доступа настроек пользователя Администрирование -> Пользователи -> USERNAME -> Настройки
        IdHTTP.Request.CustomHeaders.Values['Authorization'] :=  'user_token  ' + userToken;
        //"Настройки"->"Общие"->"API" и нажав кнопку "Добавить клиента", добавляем запись и генерируем токен (app_token)
        IdHTTP.Request.CustomHeaders.Values['App-Token'] :=  AppToken;
        //"Session-Token" получаем в функции
        IdHTTP.Request.CustomHeaders.Values['Session-Token'] := sToken ;

       //Старт  Загружаем файл
        MultiData := TIdMultiPartFormDataStream.Create;
        MultiData.AddFormField('uploadManifest', '{"input": {"name": "Документ заявки 0000", "_filename" : "DocName", "is_recursive" : true}}', 'utf-8', 'application/json').ContentTransfer := '8bit';
        with MultiData.AddFile('filename[0]','c:\testpicture01.jpg','') do //добавляем файл
          begin
                    HeaderCharset := 'utf-8';
                    HeaderEncoding := '8';
            end;
//Конец  Загружаем файл

        //GlpiRestURL - путь к вашему GLPI. Например 'http://10.0.0.10/glpi/apirest.php';
        Answer := IdHTTP.Post(GlpiRestURL + '/Document/', MultiData);  // отправляем документ

        MultiData.Free;

        //Старт Разбираем полученный ответ
        JSON := TJSONObject.ParseJSONValue(Answer) as TJSONObject;

        doc_id := JSON.Get('id').JsonValue.Value;    // Получаем ID загруженного файла

        JSON2 := TJSONObject(JSON.Get('upload_result').JsonValue);

        JSONArray := TJSONArray(JSON2.Get(0).JsonValue);

        JSON3 := TJSONObject(JSONArray.Get(0));

        doc_file := JSON3.GetValue('name').Value; // Эти значения не нужны, это для примера разбора JSON

        doc_prefix := JSON3.GetValue('prefix').Value; //Эти значения не нужны, это для примера разбора JSON
        //Конец Разбираем полученный ответ

        if (IdHttp.ResponseCode <> 200) and (IdHttp.ResponseCode <> 201)  then Result := 'Ошибка при создании заявки (' + Answer + ')'
                                       else
         begin
             // Старт Отправляем запрос на создание заявки
             IdHTTP.Request.ContentType := 'application/json';    // Это отправки json
              jsontext := '{"input": {"name": "Заявка тестовая", "content": "Описание","status":"1",' +
                '"requesttypes_id":"8","_users_id_assign":"23","time_to_resolve":"2020-06-13 18:00:00",'+
                '"itilcategories_id":"23","urgency":"3","priority":"3"}}';
              JsonToSend := TStringStream.Create(jsontext, TEncoding.UTF8);

              Answer := IdHTTP.Post(GlpiRestURL + '/Ticket', JsonToSend);

              JSON := TJSONObject.ParseJSONValue(Answer) as TJSONObject;

              newticket_id := JSON.Get('id').JsonValue.Value;    //Получяаем ID созданной заявки
              //Конец Отправляем запрос на создание заявки

              // Старт Отправляем запрос на прикрепление файла к заявке
              jsontext := '{"input": {"documents_id" : "' + doc_id + '", "items_id" : "' + newticket_id + '", "itemtype" : "Ticket" }}';
              JsonToSend := TStringStream.Create(jsontext, TEncoding.UTF8);

              Answer := IdHTTP.Post(GlpiRestURL + '/Document_Item', JsonToSend);
              //Конец Отправляем запрос на прикрепление файла к заявке

              Result := 'Заявка создана'
         end;

      finally
        IdHTTP.Free;
      end;
    finally

    end;

  except
    on E: Exception do
      ShowMessage('Error: '+E.ToString);
  end;

end;

Используется например так:

procedure TForm1.Button1Click(Sender: TObject);
Begin
GlpiUser := 'GlpiUsername';
GlpiPassword := 'SuperPassword';
GlpiRestUrl := 'http://10.0.0.10/glpi/apirest.php';
 session_token := Get_session_token;
 ShowMessage(CreateTiket(session_token));
 KillSession(session_token);
end;

вторник, 21 апреля 2020 г.

Обновление MS EXCHANGE 2013


Обновление MS EXCHANGE 2013 
Исходные данные: 2 сервера CAS и 2 сервера MBX (DAG)
P.S. Данная схема протестирована успешно при обновлении с CU13 до CU23 

Обновление CAS серверов.
1.       Подготовка (делаем резервные копии файлов и реестра для всех серверов)
Во время установки обновления Exchange 2013 все конфигурационные файлы будут перезаписываться новыми. Если вы вносили какие-либо изменения в эти файлы, то вам нужно позаботиться о том, чтобы сохранить где-либо изменения, которые вы вносили.
Ниже представлен список файлов, изменения в которых необходимо сохранить куда-либо, чтобы после установки обновления их внести заново:
- IIS: файлы web.config MBX роли (они располагаются в подпапках по пути C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess) – их изменение обычно связано, например, с интеграцией с Lync или с исправлением, когда учетная запись имеет слишком большое членство в группах
- IIS: файлы web.config CAS роли (они располагаются в подпапках по пути C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy) – их изменение обычно связано, например, с исправлением, когда учетная запись имеет слишком большое членство в группах
- Exchange: файлы *.config – конфигурационные файлы служб Exchange (они располагаются по пути C:\Program Files\Microsoft\Exchange Server\V15\Bin) – их изменение обычно связано, например, с необходимостью увеличить количество одновременных перемещений почтовых ящиков
- Exchange: реестр (расположение HKLM\Software\Microsoft\ExchangeServer\V15)

2.       Выводим обновляемый сервер из балансировки
Запускаем Панель управления\Все элементы панели управления\Администрирование\ «Диспетчер балансировки сетевой нагрузки»
На обновляемом сервере нажимаем ПКМ – Узел управления – Стоп.
Далее опять на обновляемом сервере нажимаем ПКМ – Свойства узла – Состояние по умолчание выбираем «Остановлена». Применить.

3.       Переводим сервер в режим обслуживания
В Exchange Management Shell (EMS) выполняем команду:
Set-ServerComponentState CAS02 -Component ServerWideOffline -State inactive -Requester Maintenance

4.       При необходимости устанавливаем Framework требуемой версии и Visual C++ Redistributable
- Устанавливаем Visual C++ Redistributable
- Устанавливаем Framework
- Перезагружаемся

5.       Подготавливаем Active Directory (это делается один раз на первом сервере)
Теперь перейдем в директорию с распакованным обновлением (CU) и расширим схему AD (нужен компонент Windows Server "RSAT-ADDS" и обновление безопасности) будем использовать для этого cdm.exe запущенную от Администратора:
setup.exe /prepareschema /IAcceptExchangeServerLicenseTerms
Подготовим Active Directory:
setup.exe /preparead /IAcceptExchangeServerLicenseTerms
Подготовим домен (запускается для каждого домена, содержащего почтовый сервер Exchange):
setup.exe /PrepareDomain /IAcceptExchangeServerLicenseTerms


6.       Устанавливаем обновление
- Запускаем cmd.exe.
- Переходим в папку с распакованным обновлением и запускаем обновление командой:
setup /m:Upgrade /IAcceptExchangeServerLicenseTerms
- Перезагружаем сервер.

7.        Выводим сервер из режима обслуживания
В Exchange Management Shell (EMS) выполняем команду:
Set-ServerComponentState CAS02 -Component ServerWideOffline -State active -Requester Maintenance

8.       Возвращаем сервер в балансировку
Далее опять на обновляемом сервере нажимаем ПКМ – Свойства узла – Состояние по умолчание выбираем «Работает». Применить.
На обновляемом сервере нажимаем ПКМ – Узел управления – Старт.

9.       Проверяем работоспособность
Get-ServerComponentState Name_Of_CAS_server

10.   Для других CAS серверов  все то же самое, только пропускаем пункт 1, 5


Обновление MBX серверов в DAG.

1.       Переводим сервер в режим обслуживания
В Exchange Management Shell (EMS) выполняем команды:
Set-ServerComponentState mbx01 -Component HubTransport -State Draining -Requester Maintenance

Redirect-Message -Server mbx01 -Target mbx02

Suspend-ClusterNode mbx01

Set-MailboxServer mbx01 -DatabaseCopyActivationDisabledAndMoveNow $True

Set-MailboxServer mbx01 -DatabaseCopyAutoActivationPolicy Blocked

Set-ServerComponentState mbx01 -Component ServerWideOffline -State Inactive -Requester Maintenance

2.       При необходимости устанавливаем Framework требуемой версии и Visual C++ Redistributable
- Устанавливаем Visual C++ Redistributable
- Устанавливаем Framework
- Перезагружаемся

3.       Устанавливаем обновление
- Запускаем cmd.exe.
- Переходим в папку с распакованным обновлением и запускаем обновление командой:
setup /m:Upgrade /IAcceptExchangeServerLicenseTerms
- Перезагружаем сервер.

4.        Выводим сервер из режима обслуживания
В Exchange Management Shell (EMS) выполняем команды:
Set-ServerComponentState mbx01 -Component ServerWideOffline -State Active -Requester Maintenance

Resume-ClusterNode mbx01

Set-MailboxServer mbx01 -DatabaseCopyActivationDisabledAndMoveNow $False

Set-MailboxServer mbx01 -DatabaseCopyAutoActivationPolicy Unrestricted

Set-ServerComponentState mbx01 -Component HubTransport -State Active -Requester Maintenance

5.       Проверяем работоспособность
В Exchange Management Shell (EMS) выполняем команды:
Get-ExchangeServer | ft Name, ServerRole, AdminDisplayVersion –AutoSize

Get-ClusterNode

Test-ServiceHealth

Test-MAPIConnectivity -Database maildb1 для каждой базы

Get-MailboxDatabase | Get-MailboxDatabaseCopyStatus | ft Name, Status, CopyQueueLength, ReplayQueueLength, ContentIndexState –AutoSize

Test-ReplicationHealth -Server mbx01

Get-MailboxServer | ft name, *activ*

Get-ServerComponentState mbx01

6.       Для других MBX серверов  аналогично


Полезные ссылки









понедельник, 11 сентября 2017 г.

Долго не выкладывал обновления программы Helpdesk FindUser. Сейчас готова версия 2.4.0 Описывать все изменения не буду, лучше опишу возможности текущей версии программы.



1. Программа осуществляет поиск компьютера, за которым работает пользователь, по выводимому имени, логину, ip адресу, имени компьютера,  операционной системе, подключенному принтеру. Также поиск может осуществляться только по Active Directory.
2. Редактирование данных пользователя Active Directory, смена пароля и типа входа, блокирование, разблокирование и удаление пользователя.
3. Быстрое подключение к удаленному компьютеру с помощью программ удаленного управления. Существует возможность привязывать любую программу удаленного доступа (Radmin, Dameware, ...)

четверг, 18 августа 2016 г.

Аудит подключений по VPN к Forefront TMG

При подключении к VPN серверу в журнале "Безопасности" пишутся события с ID 6278 и 6272. Ранее я писал как с помощью "Планировщика задач" можно эти события отловить и выполнить powershell скрипт, который отправить информацию на почтовый адрес.
Ниже текст скрипта.

среда, 17 августа 2016 г.

Перемещение почтовой базы на другой диск (Exchange 2013 Database Availability Group (DAG))

1. Проверяем, что с базами все в порядке и процесс архивирования завершен:
Get-MailboxDatabase -Status | format-table Name,Mounted,BackupInProgress, OnlineMaintenanceInProgress

2. Удаляем копию перемещаемой базы с пассивного сервера:
Remove-MailboxDatabaseCopy –Identity <Database name>\<Сервер> -Confirm:$False

3. Отключаем активную базу:
Dismount-Database –id <Database name> –Confirm:$False 

вторник, 28 июня 2016 г.

Аудит серверов с помощью скриптов на powershell и "Планировщика задач".

     Есть такая задача у администраторов, знать кто, когда и что. Так как на домен-контроллере события в Журнале Безопасности редко хранятся больше суток (уж больно много их плодится там), то решено было вести мониторинг с помощью отслеживания срабатывания на определенные "Event ID" в "Планировщике заданий" и последующей выборкой данных из журнала и отсылкой на почту с помощью powershell-скриптов.

четверг, 24 марта 2016 г.

Спам от имени своего домена, от самого себя (Exchange)

Столкнулся я при настройке антиспама в Exchange 2013 с такой проблемой: приходит спам либо от самого себя, либо от моего домена. Причем спам мог прийти от пользователя, которого нет в домене. Долгие ковыряние Exchange  позволили мне только лишь закидывать их в спам ящик. Microsoft никаких работающих решений не предложил и я на некоторое время отложил эту проблему, думая что с выходом нового CU все решится. CU выходили, проблема оставалась. В очередной раз копая решение этой проблемы в интернете я натолкнулся на оригинальное решение и решил его попробовать. Алелуйя, сработало.

понедельник, 28 декабря 2015 г.

Простейший мониторинг портов Cisco (Delphi 7, мои программы)

Наверное каждый администратор, сталкиваясь с сетевым оборудованием, задается вопросом о мониторинге. На моей работе так сложилось, что провода не всегда промаркированы и висят огромным "пауком". Да и вообще, я по натуре ленив и бегать, лазить, искать "концы" - это меня напрягает. Есть много различных программ и целых проектов для мониторинга. Но они либо сложно настраиваются, либо слишком громоздки (90% функционала мне не нужно). Мне нужно было получать информацию о включении и отключении портов, об access и voice vlan на портах.
Пример: я послал инженера в серверную и попросил выдернуть из сервера патч. Он дернул - я увидел в какой порт он приходит, какие vlan на нем.
https://yadi.sk/i/jU1fc2pMmZEU3

понедельник, 21 сентября 2015 г.

Обновление программы Helpdesk FindUser.

Произведено множество изменений графических и системных, добавлена возможность редактировать данные пользователя в Active Directory.
Скачать


понедельник, 14 сентября 2015 г.

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

среда, 1 июля 2015 г.

Exchange + powershell. Команды в помощь. (PowerShell)

Работать с Microsoft Exchange 2013 я начал не зная об управлении почтой ничего. Exchange 2013 был 2 недели как установлен и как выяснилось позже, кроме  обмена сообщениями не было настроено ничего. Долго и упорно я осваивал, настраивал и исправлял. Гугл конечно помогает, но даже на получение простой информации тратится много времени. Я начал вести небольшой текстовичок, в который скидывал используемые команды. Может кому-нибудь они тоже пригодятся. К каждой команде идет описание, что она делает.

воскресенье, 21 июня 2015 г.

Получение информации по SNMP (Delphi)

Появилась задача получать информацию с сетевых принтеров HP. Основная проблема это поиск необходимых OID (Object IDentificator - числовой идентификатор объекта в дереве MIB) для получения значений принтера. Вот тут есть интересная статья про MIB и OID. Информации по этому вопросу можно найти  в интернете много, поэтому приведу лишь код.


среда, 18 марта 2015 г.

Получение информации о сетевых принтерах HP (Название, имя хоста, порт, ip адрес) (VBS)

Для получения информации об установленных принтерах HP есть много способов, но мне понадобилось получить с использованием vbs. Получить список принтеров не проблема, трудности появились при получении ip адреса. Для его получения я решил воспользоваться чтением ветки реестра для каждого порта установленных принтеров: "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Print\Monitors\HP Standard TCP/IP Port". 

воскресенье, 1 марта 2015 г.

Обновлена программа поиска информации о пользователе домена

Сообщение о программе.

Выложил обновленную программу. Переименовал ее в FindUser 1.9.6Helpdesk FindUser 1.9.6
В этой версии много изменений, например теперь поиск осуществляется по всем полям без указания самого поля, проведена оптимизация обновления данных и добавлено обновление по таймеру, добавлены новые команды, изменен интерфейс и многое другое.

суббота, 28 февраля 2015 г.

Политика ограниченного использования программ

По большому счету, никаких проблем нет, но в процессе возникли некоторые нюансы, которые я хочу описать.
* По умолчанию при создании политики разрешается запуск только из системных папок "Windows" и "Program files".  Не забываем добавить для x64 систем "Program files (x86)"
* Сразу добавляем правило для закрытия всех путей ("*").  И начинаем добавлять разрешающие правила путей и программ.
* Выяснилось, что если сетевая папка подключена как сетевой диск, то путь все равно указывать сетевой полный (Например: Если папка "\\172.12.12.12\kp" подключена как диск Z:, то для разрешения запуска программ все равно указывать "\\172.12.12.12\kp").
* Для запуска доменных скриптов и программ нужно указывать путь: "\\domen.ru\SysVol\domen.ru\policies"

четверг, 27 ноября 2014 г.

Принудительное обновление адресной книги в домене (VBS)

После перевода компьютеров в новый домен начались проблемы с адресной книгой. Она перестала обновляться. Один из способов решения это отключение режима кэширования Exchange. Мне он не очень подходил и нашелся второй. Нужно было удалить вручную файлы адресной книги (*.oab) на доменных ПК. Был написан vbs скрипт и через политики домена (при входе пользователя) распространен.

воскресенье, 23 ноября 2014 г.

Настройка политик хранения Exchange 2013 для очистки папок "Удаленные" и "Нежелательная почта"

     Заставить пользователей почты очищать папки "Удаленные" и "Нежелательная почта" мне не удалось. Может, конечно, сразу стоило заняться автоматизацией этого процесса с самого начала, но я в самом начале меня не было. И так, начал я с поисков методов для решения этой проблемы и нашел, что делается все это с помощью политик хранения.

среда, 29 октября 2014 г.

Программа поиска информации о пользователе домена по ФИО или логину (Delphi, Active Directory)

     Для эффективной работы ИТ инженеров возникла необходимость получать сведения об ip адресе и имени компьютера по логину или Фамилии пользователя.

Исходные данные таковы:
 - логин пользователя домена - это ФИО в транслите (пример для Иванова Михаила Владимировича - mvivanov)
- Атрибуты пользователя домена заполнены так:
      "Имя" - Михаил Владимирович
      "Фамилия" - Иванов
      "Выводимое имя" - Иванов М.В.

суббота, 11 октября 2014 г.

Скрипт импорта номеров телефонов и ip-телефонов в данные пользователей Active Directory (PoweShell)

Для актуализации данных пользователей домена понадобилось сделать импорт телефонного справочника с номерами телефонов и ip телефонов.