Тема: JScript: Вывод списка пользователей на каждом контроллере домена...
... с указанием даты последнего входа пользователя в домен.
Поскольку пользователь мог ни разу не входить в домен, дата входа в зависимости от версии Windows Server (2000, 2003) может быть как 0, так и null (<Not Set>). Если дата входа равна 0, то она выводится как "1 января 1601 г. 0:00:00". Если она равна null, то выдается сообщение "Значение lastLogon для текущего пользователя отсутствует".
Скрипт может (и должен) использоваться для отслеживания неактивных пользователей.
Оговорка - делать на основе этого скрипта автоматическое удаление неактивных пользователей нужно осторожно, так как в неактивных могут присутствовать пользователи, созданные системой автоматически для своих нужд. Удалять их не рекомендуется. В теме http://forum.script-coding.com/viewtopic.php?id=859 были попытки найти способ отличить системных пользователей от "ручных", но универсальный способ пока не найден.
За помощь в тестировании скрипта и высказанные замечания спасибо alexii.
var WSH = new ActiveXObject ('WScript.Shell');
// Если скрипт запущен через WScript, ругаемся и выходим
if (WScript.FullName.toLowerCase() == (WScript.Path+'\\wscript.exe').toLowerCase()) {
WSH.Popup('Запуск сценария производится только через '+WScript.Path+'\\cscript.exe.\n\nВыходим...', 0, 'Ошибка', 16);
WScript.Quit();
}
var Stdout = WScript.Stdout;
var Stdin = WScript.Stdin;
var objDict = new ActiveXObject("Scripting.Dictionary");
var objConnection = new ActiveXObject("ADODB.Connection");
var objCommand = new ActiveXObject("ADODB.Command");
var oRoot = GetObject("LDAP://rootDSE");
var sDomain = oRoot.Get("defaultNamingContext");
var strLDAP = "LDAP://OU=Domain Controllers," + sDomain;
var ADS_SCOPE_SUBTREE = 2;
var space = ' ';
var date1601 = Math.abs((new Date(1601,0,1)).getTime())
var strDC, temp, arr
// Формируем запрос на поиск всех серверов домена ========================
objConnection.Provider = "ADsDSOObject";
objConnection.Open("Active Directory Provider");
objCommand.ActiveConnection = objConnection;
objCommand.Properties("Page Size") = 500;
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE;
objCommand.Properties("Sort On") = "sAMAccountName";
objCommand.CommandText = "SELECT sAMAccountName,adsPath FROM '" + strLDAP + "' WHERE objectCategory='computer'";
// =======================================================================
// Выполняем запрос
var objRSServers = objCommand.Execute;
// Перебираем все найденные серверы и добавляем юзеров в глобальный
// для сценария словарь objDict (в функции GetUsers)
while ( !objRSServers.EOF ) {
strDC = objRSServers.Fields("sAMAccountName").Value;
GetUsers(strDC.substr(0, strDC.length-1 ));
objRSServers.moveNext()
}
// сортируем логины по алфавиту
arr = (new VBArray(objDict.Keys())).toArray();
for (var i = arr.length - 1; i>=0; i--) {
for (var j= 0; j<i; j++) {
if ( arr[j]>arr[j+1] ) {
temp=arr[j+1];
arr[j+1]=arr[j];
arr[j]=temp;
}
}
}
// Перебираем всех найденных юзверей
var name, lastLogon, age, Item
var comment = ' <Значение lastLogon для текущего пользователя отсутствует>';
for (var usr in arr)
{
name = arr[usr];
Stdout.Write( (name+space).substr(0,30) );
lastLogon = objDict(name);
if(lastLogon instanceof Date) {
age = (new Date() - lastLogon)/(86400*1000);
Stdout.WriteLine( ("Дата последнего входа: " +(lastLogon).toLocaleString()+space).substr(0,53)+
"("+(space+age.toFixed(0)).slice(-7)+" дней назад)" );
} else {
Stdout.WriteLine( comment );
}
}
Stdout.WriteLine ("\nНажмите Enter");
Stdin.ReadLine ();
//
// FUNCTIONS
//
// Выбирает всех пользователей на заданном сервере домена в ассоциативный массив
function GetUsers( strDC ) {
var dLastLogin;
var Conn = new ActiveXObject("ADODB.Connection");
var RSUsers = new ActiveXObject ("ADODB.Recordset");
var query = "SELECT sAMAccountName, lastLogon FROM 'LDAP://" + strDC + "' WHERE objectCategory='user'"
Stdout.WriteLine("Список пользователей на: " + strDC);
Conn.Provider = "ADsDSOObject";
Conn.Open("Active Directory Provider");
RSUsers.ActiveConnection = Conn;
for ( RSUsers.Open (query); !RSUsers.EOF; RSUsers.moveNext() ) {
// Для уникальности имени добавляем к нему имя DC
sAMAccountName = strDC+": "+RSUsers.Fields("sAMAccountName").Value;
if ( dLastLogin = RSUsers.Fields("lastLogon").Value ) {
// сюда попадаем, когда у атрибута есть значение (любое)
dLastLogin = getLast(dLastLogin);
} else {
// сюда попадаем, когда атрибута нет значения (<Not Set>)
}
AddToDict(sAMAccountName, dLastLogin)
}
}
// добавляет в ассоциативный массив значение с примечанием
function AddToDict(name, value) {
if (!objDict.Exists (name) ) {
objDict.Add ( name, value );
} else {
objDict(name) = value;
}
}
// конвертирует lastLogon, возвращенный запросом к LDAP, в удобоваримую дату
function getLast( last ) {
var res,
intLastLogonTime = last.HighPart* (4294967296) + last.LowPart;
res = intLastLogonTime / 10000;
res = res - date1601;
return (new Date(res));
}