Статистика входов / выходов пользователей в базу на основе GPO, VBS, MySQL

Не так давно, в 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:{impersonationLevel=impersonate}!\\» & strComputer & «\root\cimv2»)
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

Скрипт LogOnOff.vbs
Пример как добавить скрипт в GPO

Суть скрипта проста, в зависимости от атрибута происходит обновление в Active Directory поля «описание» компьютеров. Ну, захотелось сохранить эту возможность, что поделаешь. Дальше, идёт считывание основных параметров сессии пользователя с отправкой данных через POST запрос на сервер, где работает связка Apache+PHP+MySQL.

Обратите внимание на параметры сценариев GPO (logoff и logon), от них зависит как будет работать скрипт, если не укажите, то скрипт выполнится, но без каких либо последствий.

На сервере, в моём случае это ubuntu server установленный в виртуальной среде Hyper-V, но это не важно, следующий php код разбирает полученные POST данные и заносит в базу mysql.

Вот и сам скрипт add.php:

<?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-скрипт отображения данных:

<?php
header(«Cache-Control: no-cache, must-revalidate»); // HTTP/1.1
ini_set(«display_errors»,»On»);
error_reporting(E_ALL);

require(«config.php»); //config

mysql_connect(MYSQL_SERVER, MYSQL_LOGIN, MYSQL_PASSWORD) OR DIE(«Не могу создать соединение «);
mysql_select_db(MYSQL_DATABASE) or die(mysql_error());
?>
<html>
<head>
<meta http-equiv=»content-type» content=»text/html; charset=utf-8″ />
<title>Логи вход/выход пользователей домена NFK.ARGUS.CIS</title>
<style type=»text/css» title=»currentStyle»>
@import «/js/dataTables/css/demos.css»;
</style>
<script type=»text/javascript» src=»/js/jquery-1.8.2.min.js»></script>
<script type=»text/javascript» src=»/js/jquery.dataTables.js»></script>
<script type=»text/javascript» charset=»utf-8″>
$(document).ready(function() {
$(‘#example’).dataTable(
{
«oLanguage»: {«sUrl»: «/js/dataTables/ru_RU.txt»},
«iDefaultSortIndex»: 0,
«sDefaultSortDirection»: «desc»
}
);
} );
</script>
</head>
<body>
<?php
$query = «Select * from UserLogons ORDER BY `UserLogons`.`date` DESC LIMIT 0 , 2000″;
$res = mysql_query($query) or die(mysql_error());
?>
<p>Выборка последних 2000 записей:</p>
<table cellpadding=»0″ cellspacing=»0″ border=»0″ id=»example» class=»display»>
<thead>
<tr>
<th>Дата Время</th>
<th>ФИО</th>
<th>Логин</th>
<th>Действие</th>
<th>Компьютер</th>
<th>DHCP</th>
<th>IP-адрес</th>
<th>MAK-адрес</th>
<th>Сетевые диски</th>
</tr>
</thead>
<tbody>
<?
function ActionLogin($i) {
if ($i == «0») return «выход»;
if ($i == «1») return «вход»;
}
function DHCP($i) {
if ($i == «0») return «<font color=red>выкл</font>»;
if ($i == «1») return «вкл»;
}
while ($row=mysql_fetch_array($res))
{
?>
<tr>
<td class=»date»><? echo $row[‘date’]; ?></td>
<td><? echo $row[‘username’]; ?></td>
<td><? echo $row[‘samaccountname’]; ?></td>
<td><? echo ActionLogin($row[‘login’]); ?></td>
<td><? echo $row[‘computername’]; ?></td>
<td><? echo DHCP($row[‘DHCPEnabled’]); ?></td>
<td><? echo $row[‘ip’]; ?></td>
<td><? echo $row[‘mac’]; ?></td>
<td><? echo $row[‘netdrives’]; ?></td>
</tr>
<?
}
?>
</tbody>
</table>
</body>
</html>

Опять же, скрипт достаточно прост и разбирать его не стоит, его единственная функция — формирование данных из базы в одну таблицу.

Напоследок выложу исходники целиком, это кому лень копировать-вставить: LogOnOff

Будут вопросы — обращайтесь 🙂 Возможно мне ещё раз понадобится ещё модернизировать статистику — выложу результат.

Рекомендовать Google:
.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*