Тема: HTA: Active Directory Objects Finder
В общем то я всегда обходился консольной dsquery для поиска и Русиновичевским ADExplorer для детализации.
Мелкософтовский RSAT с его "Центром администрирования" использую крайне редко (уж больно он тяжелый).
А тут товарищу понадобилось находить некие атрибуты учеток которые через стандартный аплет "Active Directory Users and Computers" найти чрезвычайно сложно.
Вот тогда и была написана это HTA-шка.
Помимо собственно пользователей, которых можно искать как по логину так и по имени (или части его) ищет компьютеры, группы, контакты и другие объекты AD.
Результаты снабжены названием типа объекта и раскрашены разными цветами, так что не перепутаете.
Выбрав в комбобоксе с результатами конкретный объект можно просмотреть имена и значения всех его атрибутов.
Пока выводятся только необработанные строковые данные. В будущем планируется преобразовывать их к более наглядному виду.
Также в планах преобразование данных других типов, расширение критериев поиска, подключение к другоиу домену и т.д. и пр.
Если есть желание подключится к совместной разработке - Welcome!
Код старался писать максимально наглядно чтобы желающие могли использовать его в своих злостных целях.
Тут выкладываю самый первый вариант поскольку в нем вся работа с AD написана на vbscript, который многим кажется проще.
<html>
<head>
<meta http-equiv=content-type content="text-html; charset=utf-8">
<meta http-equiv=MSThemeCompatible content=yes>
<hta:application
id="App"
applicationName="Active Directory Objects Finder"
innerBorder="no"
icon="usercpl.dll"
scroll="no"
singleInstance="yes"
version="0.0.0"
autor="mozers™"
/>
<style type="text/css">
* {font:10pt verdana;}
body {margin:0px;}
table {border-width:0; border-collapse:collapse;}
td {white-space:nowrap;}
.top {height:80px; font:10px courier new; background-color:buttonface;}
.top td {padding:0px 4px 0px 8px;}
#idResult td {font:8pt MS Shell Dlg; padding:0px 2px 0px 4px; border-bottom:1px dotted gray;}
</style>
<script type="text/javascript">
document.title = App.applicationName + ' v.' + App.version;
window.resizeTo(900,500);
// Добавляет новый пункт с данными заданного объекта в комбобокс
function AddOption (sLDAP) {
var oOption = document.createElement("option");
oOption.value = sLDAP;
oOU = GetObject(sLDAP);
oOption.text = '[' + oOU.Class + '] ' + oOU.cn;
switch(oOU.Class){
case 'user': oOption.style.color = "green"; break;
case 'computer': oOption.style.color = "blue"; break;
case 'group': oOption.style.color = "gray"; break;
}
idSelResult.add(oOption);
}
// Добавляет новую строчку с данными content1 и content2 в таблицу свойств-значений
function AddRow (content1, content2) {
var r = idResult.insertRow();
r.insertCell().innerText = content1;
r.insertCell().innerText = content2;
}
// Удаляет все дочерние элементы заданного узла
function RemoveChildren(node) {
while (node.firstChild) node.removeChild(node.firstChild);
}
// Показ всех свойств-значений выбраного в комбобоксе объекта AD
function ShowADObject() {
RemoveChildren(idResult);
if (idSelResult.options.length){
EnumerateADObject(idSelResult.options[idSelResult.selectedIndex].value);
}
}
// Запуск поиска объектов
function FindADObjects(){
RemoveChildren(idSelResult);
GetADInfo(idObjName.value);
ShowADObject();
}
</script>
</head>
<body onload="idObjName.focus();" style="width:100%;">
<table style="height:100%; width:100%">
<tr>
<td class="top">
<table style="width:100%;">
<tr>
<td style="width:100%;"><input id="idObjName" onkeydown="if (event.keyCode==13) FindADObjects()" type="text" style="width:100%;"></td>
<td><button onClick="FindADObjects()" hidefocus><b>Поиск</b></button></td>
</tr>
<tr>
<td style="width:100%;"><select id="idSelResult" onselect="ShowADObject()" onchange="ShowADObject()" style="width:100%;"></select></td>
<td><b>[<span id="idCount">0</span>]</b></td>
</tr>
</table>
<hr size="1px">
</td>
</tr>
<tr>
<td>
<div style="height:100%; width:100%; overflow-y:scroll; overflow-x:hidden;">
<table id="idResult" style="width:100%;"></table>
</div>
</td>
</tr>
</table>
</body>
<script type="text/vbscript">
' Возвращает информацию о объектах Active Directory
' Входные данные: часть имени объекта (cn или sAMAccountName)
' Найденные LDAP Strigs помещает в комбобокс
Sub GetADInfo(str)
Set ADOConnection = CreateObject("ADODB.Connection")
ADOConnection.Provider = "ADsDSOObject"
ADOConnection.Open "Active Directory Provider"
strDNSDomain = GetObject("LDAP://RootDSE").Get("defaultNamingContext")
Set adoCommand = CreateObject("ADODB.Command")
adoCommand.ActiveConnection = ADOConnection
adoCommand.Properties("Page Size") = 1000
adoCommand.Properties("Searchscope") = 2 'ADS_SCOPE_SUBTREE
adoCommand.CommandText = "SELECT * FROM 'LDAP://" & strDNSDomain & "' WHERE cn='" & str & "*' OR sAMAccountName='" & str & "*'"
Set adoRecordSet = adoCommand.Execute
idCount.innerText = adoRecordSet.RecordCount
If adoRecordSet.RecordCount = 0 Then Exit Sub
adoRecordSet.MoveFirst
Do Until adoRecordSet.EOF
AddOption adoRecordSet(0).Value
adoRecordSet.MoveNext
Loop
ADOConnection.Close
End Sub
' Перечисляет все свойства выбранного объекта AD
Sub EnumerateADObject(sLDAP)
Set oAD = GetObject(sLDAP)
Set oSchema = GetObject(oAD.Schema)
For Each prop In oSchema.mayContain
GetProperty oAD, prop
Next
End Sub
' Пробует извлечь из Obj значение c именем name
' Если получается - дополняет сторкой таблицу имясвойства - значение
' TODO: Далеко не все значения хранятся как String. Необходимо дописать обработку других типов данных.
Sub GetProperty(obj, name)
On Error Resume Next
v = obj.Get(name)
If Err.Number <> 0 Then Exit Sub
AddRow name, CStr(v)
End Sub
</script>
</html>
Доработанная и обновляемая версия (уже на чистом javascript) лежит тут.
Конечно жду критики и предложений. Ради этого все и делается...