[Из песочницы] Удобный поиск компьютера пользователя в домене Windows

Привет всем! Работаю в компании. 1500+ активных пользователей.Организован ХелпДеск, сотрудники регистрируют тикеты в системе, но, как-то так получается, что часть из юзеров забывают указывать имя пк, за которым они находятся.Для выяснения этой информации (по телефону/email/экстрасенсорные способности) девочки из поддержки тратят драгоценное время, которое они могли бы уделить свежей чашке кофе или разговорам о новом платье (шутка). Наши сотрудники постоянно заняты своей непосредственной работой.Идея (не инновация конечно) — писать данные о логонах пользователя в единую базу, а потом через веб оперативно искать нужную информацию.

image

Что у нас есть? Windows среда (ХР/7/2003/2008), учетные записи хранятся в AD, все устройства работаю в локальной сети в качестве СУБД используем MSSQL 2005/2008R2.Что мы хотим? Поиск информации через веб интерфейс: Где логинился сотрудник с фамилией, например, «Иванов»; Кто логинился на устройстве, например, «PC34»; Где были совершены логоны под учетной записью, например, «hr.ivanov». Должна отображаться информация:

имя пк; login; фио; ip адрес; дата логона. Название? Так как «решением» будут пользоваться несколько человек (от 5 до 35 человек), надо как-то его обозвать для удобства. Нарекли мы его «SuperVisor».Приступим к реализации Как будем писать в БД? Первое, что пришло в голову — это создать bat файл с sqlcmd, но для каждой версии Windows нужна своя версия утилиты sqlcmd. Неудобно, и мы не стали копать глубже.

Вторым решением было создать небольшой exe клиент, который при запуске будет собирать данные об имени доменной учетной записи, имени пк, ip адресе пк и после получения этой информации будет выполняться вставка данных в БД. Программу размещаем, например, в папке NETLOGON на контроллере домена и групповыми политиками распространяем на ПК/Сервера в локальной сети компании.

Программа на Delphi unit Unit1; interface uses Windows, SysUtils, Variants, Classes, Forms, WinSock, Dialogs, DB, ADODB, StdCtrls, Messages, ExtCtrls; type TForm1 = class (TForm) boston: TADOConnection; qryinsert: TADOQuery; timer: TTimer; procedure FormCreate (Sender: TObject); procedure timerTimer (Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1;

implementation

{$R *.dfm} // версия 0.0.4 // дата 27–02–2014

function GetCurrentUserName: string; const cnMaxUserNameLen = 254; var sUserName: string; dwUserNameLen: DWORD; begin dwUserNameLen:= cnMaxUserNameLen — 1; SetLength (sUserName, cnMaxUserNameLen); GetUserName (PChar (sUserName), dwUserNameLen); SetLength (sUserName, dwUserNameLen); Result:= string (sUserName); end;

function GetCurrentComputerName: string; const cnMaxComputerNameLen = 254; var sComputerName: string; dwComputerNameLen: DWORD; begin dwComputerNameLen:= cnMaxComputerNameLen — 1; SetLength (sComputerName, cnMaxComputerNameLen); GetComputerName (PChar (sComputerName), dwComputerNameLen); SetLength (sComputerName, dwComputerNameLen); Result:= string (sComputerName); end;

function GetLocalIP: String; const WSVer = $101; var wsaData: TWSAData; P: PHostEnt; Buf: array [0…127] of Char; begin Result:= ''; if WSAStartup (WSVer, wsaData) = 0 then begin if GetHostName (@Buf, 128) = 0 then begin P:= GetHostByName (@Buf); if P <> nil then Result:= iNet_ntoa (PInAddr (p^.h_addr_list^)^); end; WSACleanup; end; end;

procedure TForm1.FormCreate (Sender: TObject); begin try qryinsert.SQL.Text:= 'begin TRANSACTION insertdata' +#13#10 + 'insert into [supervisor].[user].[info_host](host, login, last_ip) values (: host,: login,: ip)'+#13#10 + 'COMMIT TRANSACTION insertdata'; qryinsert.Parameters.ParamByname ('login').Value:= GetCurrentUserName; qryinsert.Parameters.ParamByname ('host').Value:= GetCurrentComputerName; qryinsert.Parameters.ParamByname ('ip').Value:= GetLocalIP; qryinsert.ExecSQL; timer.Enabled:=True; form1.timer.Interval:=1500; except Application.Terminate; end end;

procedure TForm1.timerTimer (Sender: TObject); begin ExitProcess (0); end; end. Дальше алгоритм такой:

Пользователь логинится за пк; Скрытно запускается SuperVisor.exe; Делается попытка INSERT в указанную бд, если успешно, то программа завершает свою работу; Если выполнить INSERT не получается (ноутбук не в локальной сети, сервер бд недоступен и т.д), таймаут 15 секунд и процесс «убивается», не пугая пользователя страшными сообщениями и окнами. Отлично, теперь создадим таблицы, в которых будут храниться данные /*

Главная таблица, в которую пишутся логоны ----------------------------------------------------------- host — имя пк login — имя доменной учетной записи last_ip — ip адрес пк createdate — дата создания записи createdate_unix — unix время, дата создания записи ------------------------------------------------------------

*/

CREATE TABLE [user].[info_host]( [id] [int] IDENTITY (1,1) NOT NULL, [host] [nvarchar](128) NULL, [login] [nvarchar](128) NULL, [createdate] [datetime] NOT NULL, [createdate_unix] [int] NOT NULL, [last_ip] [nvarchar](20) NULL ) ON [supervisor]

GO

ALTER TABLE [user].[info_host] ADD DEFAULT (getdate ()) FOR [createdate] GO

ALTER TABLE [user].[info_host] ADD DEFAULT (datediff (second,'1970–01–01 00:00:00', getutcdate ())) FOR [createdate_unix] /*

Таблица справочник с ФИО учетных записей, наполняется из АД. Синхронизация происходит один раз в сутки ------------------------------------------------------------ login — имя доменной учетной записи displayName — поле displayname из АД для учетной записи createdate — дата создания записи createdate_unix — unix время, дата создания записи ------------------------------------------------------------

*/

CREATE TABLE [user].[info_login_card]( [id] [int] IDENTITY (1,1) NOT NULL, [login] [nvarchar](128) NULL, [createdate] [datetime] NOT NULL, [createdate_unix] [int] NOT NULL, [displayName] [nvarchar](256) NULL ) ON [supervisor]

GO

ALTER TABLE [user].[info_login_card] ADD DEFAULT (getdate ()) FOR [createdate] GO

ALTER TABLE [user].[info_login_card] ADD DEFAULT (datediff (second,'1970–01–01 00:00:00', getutcdate ())) FOR [createdate_unix] GO Таблицы созданы и наполняются данными. Забыл написать, что сервер БД у нас виртуальный и работает под Windows Server 2003R2, СУБД MSSQL 2008R2. Сервер приложения виртуальный, Windows 2003R2, Apache 2.2 + PHP 5.2

Следующий шаг — создание веб интерфейса для того, чтобы системные администраторы и сотрудники хелпдеска могли комфортно работать с сервисом. Во внутренних разработках, для экономии времени, я использую фреймфорк Bootstrap. Главная страница, до того как начинают вводить данные в поисковую строку, выглядит так:

image

В строку поиска можно ввести фамилию сотрудника/учетную запись (логин) или имя компьютера:

image

Причем, не обязательно вводить полностью фамилию и имя сотрудника/логин/имя пк, поиск совпадений в БД осуществляется с помощью оператора LIKE (пример …LIKE 'ива%'), запросы выполняются асинхронно, результат поиска обновляется перед глазами сотрудника без перезагрузки страницы после ввода нового символа в строку поиска.

запрос к бд для поиска по ФИО set rowcount $limit SELECT a.[id] , a.[host] , a.[login] , a.[createdate] , a.[createdate_unix] , a.[last_ip] , b.[displayName] FROM [user].[info_host] a left join [user].[info_login_card] b on a.login = b.login where b.displayName like ('$ihostlogin') order by a.[createdate_unix] desc set rowcount 0 запрос к бд для поиска по имени пк set rowcount $limit SELECT a.[id] , a.[host] , a.[login] , a.[createdate] , a.[createdate_unix] , a.[last_ip] , b.[displayName] FROM [user].[info_host] a left join [user].[info_login_card] b on a.login = b.login where a.host like ('$hostlogin') order by a.[createdate_unix] desc set rowcount 0 поиск по логину set rowcount $limit SELECT a.[id] , a.[host] , a.[login] , a.[createdate] , a.[createdate_unix] , a.[last_ip] , b.[displayName] FROM [user].[info_host] a left join [user].[info_login_card] b on a.login = b.login where a.login like ('$hostlogin') order by a.[createdate_unix] desc set rowcount 0 «Супервизор» работает у нас в компании около года, со своей главной задачей справляется отлично. Тикеты теперь берутся в работу оперативнее, сотрудникам не нужно тратить время на уточнение дополнительной информации для того, чтобы преступить к решению заявки.

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

Успехов в работе!

Полезные ссылки Установка Apache2.2 и PHP-5; Подключение MS SQL к PHP 5.3 и выше.

© Habrahabr.ru