Привет всем!
Работаю в компании. 1500+ активных пользователей.
Организован ХелпДеск, сотрудники регистрируют тикеты в системе, но, как-то так получается, что часть из юзеров забывают указывать имя пк, за которым они находятся.
Для выяснения этой информации (по телефону/email/экстрасенсорные способности) девочки из поддержки тратят драгоценное время, которое они могли бы уделить свежей чашке кофе или разговорам о новом платье (шутка). Наши сотрудники постоянно заняты своей непосредственной работой.
Идея (не инновация конечно) — писать данные о логонах пользователя в единую базу, а потом через веб оперативно искать нужную информацию.
Что у нас есть?
Windows среда (ХР/7/2003/2008), учетные записи хранятся в AD, все устройства работаю в локальной сети в качестве СУБД используем MSSQL 2005/2008R2.
Что мы хотим?
Поиск информации через веб интерфейс:
- Где логинился сотрудник с фамилией, например, "Иванов";
- Кто логинился на устройстве, например, "PC34";
- Где были совершены логоны под учетной записью, например, "hr.ivanov".
Должна отображаться информация:
- имя пк;
- login;
- фио;
- ip адрес;
- дата логона.
Название?
Так как «решением» будут пользоваться несколько человек (от 5 до 35 человек), надо как-то его обозвать для удобства. Нарекли мы его «SuperVisor».
Приступим к реализации
Как будем писать в БД?
Первое, что пришло в голову — это создать bat файл с sqlcmd, но для каждой версии Windows нужна своя версия утилиты sqlcmd. Неудобно, и мы не стали копать глубже.
Вторым решением было создать небольшой exe клиент, который при запуске будет собирать данные об имени доменной учетной записи, имени пк, ip адресе пк и после получения этой информации будет выполняться вставка данных в БД. Программу размещаем, например, в папке NETLOGON на контроллере домена и групповыми политиками распространяем на ПК/Сервера в локальной сети компании.
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. Главная страница, до того как начинают вводить данные в поисковую строку, выглядит так:
В строку поиска можно ввести фамилию сотрудника/учетную запись(логин) или имя компьютера:
Причем, не обязательно вводить полностью фамилию и имя сотрудника/логин/имя пк, поиск совпадений в БД осуществляется с помощью оператора 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 и выше.
Автор: rus74