Не так давно, в Active Directory, я начал заносить в поле «описание» компьютеров время входа и выхода через GPO. Примеров того, как это можно сделать полно в интернете, вдаваться в подробности не будем. Все работает и сейчас, но меня напрягло то, что нет статистики по входам – выходам пользователей с рабочих станций. Решил это исправить.
Самое простое решение – заносить статистику для каждого компьютера в текстовый файл, на общедоступной папке. Даже сделал этот вариант, но показалось неудобно, нечитабельно. Для себя решил, что статистика должна складываться в базу данных, предпочтительнее mysql и визуализироваться через web интерфейс.
Так как мои знания в vbs скриптинге, скажем прямо, не очень хороши, то решил погуглить, вспомнив, что где-то видел пример, подходящий под мои требования. Нашёл тот сайт: http://msadlogging.blogspot.ru/
Сделал всё по инструкции, по пути исправил несколько незначительных ошибок. Заработало. Я доволен. Решил навести тюнинг.
VBS — скрипт, запускаемый через GPO при входе и выходе пользователей я назвал LogOnOff.vbs, вот собственно и он сам:
On Error Resume Next
args = WScript.Arguments.Count
If args <> 1 then
WScript.Quit
end If
if (WScript.Arguments.Item(0) = «logoff») Then login=»0″ End If ‘Выход
if (WScript.Arguments.Item(0) = «logon») Then login=»1″ End If ‘Вход
‘заносим информацию в АД
Dim adsinfo, ThisComp, oUser, DescText
if (login = «0») Then
On Error Resume Next
Set adsinfo = CreateObject(«adsysteminfo»)
Set ThisComp = GetObject(«LDAP://» & adsinfo.ComputerName)
Set oUser = GetObject(«LDAP://» & adsinfo.UserName)
DescText = «LogOf: » + oUser.fullname + » » + CStr(Now)
Thiscomp.put «description», DescText
ThisComp.Setinfo
End If
if (login = «1») Then
On Error Resume Next
Set adsinfo = CreateObject(«adsysteminfo»)
Set ThisComp = GetObject(«LDAP://» & adsinfo.ComputerName)
Set oUser = GetObject(«LDAP://» & adsinfo.UserName)
DescText = «LogOn: » + oUser.fullname + » » + CStr(Now)
Thiscomp.put «description», DescText
ThisComp.Setinfo
End If
‘заносим информацию в базу данных
Set objNetwork = CreateObject(«Wscript.Network»)
Set objSysInfo = WScript.CreateObject(«ADSystemInfo»)
strComputer = «.»
Set objWMIService = GetObject(«winmgmts:!\» & strComputer & «rootcimv2»)
Set colAdapters = objWMIService.ExecQuery («SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = True»)
Dim ip, mac, dhcp
For Each objAdapter in colAdapters
If Not IsNull(objAdapter.IPAddress) Then
For i = 0 To UBound(objAdapter.IPAddress)
ip = ip & objAdapter.IPAddress(i) & » »
Next
mac = mac & objAdapter.MACAddress & » »
End If
dchp = objAdapter.DHCPEnabled
Next
Dim param
if (login = 0 or login = 1) Then
strUserDN = objSysInfo.UserName
Set objUser = GetObject(«LDAP://» & strUserDN)
Dim netdrives
Set objDrive = objNetwork.EnumNetworkDrives()
For intDrive = 0 To (objDrive.Count-1) Step 2
netdrives = netdrives & objDrive.Item(intDrive) & objDrive.Item(intDrive+1) & » »
Next
param = «username=» & (objUser.DisplayName) & «&» & _
«samaccountname=» & (objNetwork.UserName) & «&» & _
«login=» & (login) & «&» & _
«computername=» & (objNetwork.ComputerName) & «&» & _
«ip=» & (ip) & «&» & _
«mac=» & (mac) & «&» & _
«netdrives=» & (netdrives)
if (dchp) Then
param = param & «&» & «DHCPEnabled=1»
Else
param = param & «&» & «DHCPEnabled=0»
End If
End If
Set objHTTP = CreateObject(«Microsoft.XMLHTTP»)
objHTTP.open «POST», «http://10.72.80.28/LogOnOff/add.php», False
objHTTP.setRequestHeader «Content-Type», «application/x-www-form-urlencoded»
objHTTP.send param
‘WScript.Echo param
Set objHTTP = Nothing
Суть скрипта проста, в зависимости от атрибута происходит обновление в Active Directory поля «описание» компьютеров. Ну, захотелось сохранить эту возможность, что поделаешь. Дальше, идёт считывание основных параметров сессии пользователя с отправкой данных через POST запрос на сервер, где работает связка Apache+PHP+MySQL.
Обратите внимание на параметры сценариев GPO (logoff и logon), от них зависит как будет работать скрипт, если не укажите, то скрипт выполнится, но без каких либо последствий.
На сервере, в моём случае это ubuntu server установленный в виртуальной среде Hyper-V, но это не важно, следующий php код разбирает полученные POST данные и заносит в базу mysql.
Вот и сам скрипт add.php:
header(«Cache-Control: no-cache, must-revalidate»); // HTTP/1.1
ini_set(«display_errors»,»Off»);
require(«config.php»); //config
mysql_connect(MYSQL_SERVER, MYSQL_LOGIN, MYSQL_PASSWORD) OR DIE(«Не могу создать соединение «);
mysql_select_db(MYSQL_DATABASE) or die(mysql_error());
if (isset($_POST[‘username’]) and isset($_POST[‘samaccountname’]) and isset($_POST[‘login’]) and isset($_POST[‘computername’]) and isset($_POST[‘ip’]) and isset($_POST[‘mac’]) and isset($_POST[‘netdrives’]))
$username = ($_POST[‘username’]);
$samaccountname = ($_POST[‘samaccountname’]);
$login = ($_POST[‘login’]);
$computername= ($_POST[‘computername’]);
$DHCPEnabled = $_POST[‘DHCPEnabled’];
$ip = ($_POST[‘ip’]);
$mac = ($_POST[‘mac’]);
$netdrives = ($_POST[‘netdrives’]);
$query = «INSERT INTO UserLogons VALUES (NOW(), ‘».$username.»‘, ‘».$samaccountname.»‘, ‘».$login.»‘, ‘».$computername.»‘, ‘».$DHCPEnabled.»‘, ‘».$ip.»‘, ‘».$mac.»‘,’».addslashes($netdrives) .»‘)»;
$res = mysql_query($query) or die(mysql_error());
>
?>
Вот запрос на создание таблицы в базе данных, не идеальной конечно, но всё же работающей:
CREATE TABLE IF NOT EXISTS `UserLogons` (
`date` datetime NOT NULL,
`username` varchar(70) NOT NULL,
`samaccountname` varchar(30) NOT NULL,
`login` tinyint(1) NOT NULL,
`computername` varchar(35) NOT NULL,
`DHCPEnabled` float NOT NULL,
`ip` varchar(90) NOT NULL,
`mac` varchar(110) NOT NULL,
`netdrives` varchar(300) NOT NULL,
KEY `idx_date` (`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Так, данные заносятся в базу, осталось визуализировать в удобном виде. Просто тупо выводить всю таблицу считаю нецелесообразным. Решил навесить довольно удобный плагин jquery.dataTables, использующий довольно популярную библиотеку JavaScript – jQuery. Цель – выводить постранично и с функцией поиска. Т.к. база в итоге может быть очень большой, то и ограничил количество строк в запросе количеством в 2000, у меня это примерно неделя статистики. Вот и сам php-скрипт отображения данных:
Опять же, скрипт достаточно прост и разбирать его не стоит, его единственная функция — формирование данных из базы в одну таблицу.
Напоследок выложу исходники целиком, это кому лень копировать-вставить: LogOnOff
Будут вопросы — обращайтесь 🙂 Возможно мне ещё раз понадобится ещё модернизировать статистику — выложу результат.