<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; HTA: Active Directory Objects Finder]]></title>
	<link rel="self" href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=11509&amp;type=atom" />
	<updated>2016-05-06T22:35:44Z</updated>
	<generator>PunBB</generator>
	<id>https://forum.script-coding.com/viewtopic.php?id=11509</id>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103427#p103427" />
			<content type="html"><![CDATA[<p>Я понимаю. В комбинированном HTA особо и нет смысла заморачиваться. А так ...:<br /></p><div class="codebox"><pre><code>With CreateObject(&quot;ScriptControl&quot;) .Language = &quot;JScript&quot; : b = .Eval(&quot;new Date().getTimezoneOffset()*60000&quot;) End With</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Flasher]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27593</uri>
			</author>
			<updated>2016-05-06T22:35:44Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103427#p103427</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103417#p103417" />
			<content type="html"><![CDATA[<p>2<strong>Flasher</strong><br />Можно и так, можно и как в примере 2 постами выше. Но это же не встроенные функции, как <span style="color: blue">Date.getTimezoneOffset()</span> в JS.</p>]]></content>
			<author>
				<name><![CDATA[mozers]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4112</uri>
			</author>
			<updated>2016-05-06T17:50:55Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103417#p103417</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103380#p103380" />
			<content type="html"><![CDATA[<div class="quotebox"><cite>mozers пишет:</cite><blockquote><p>ActiveTimeBias - текущий часовой пояс. В VBS нет встроенных функций для его извлечения</p></blockquote></div><p>&gt;&gt;&gt;<br /></p><div class="codebox"><pre><code>strComputer = &quot;.&quot;
Set WMI = GetObject(&quot;winmgmts:\\&quot; &amp; strComputer &amp; &quot;\root\CIMV2&quot;)
For Each Item in WMI.ExecQuery(&quot;SELECT Bias, Caption, Description, DayLightName, StandardName FROM Win32_TimeZone&quot;)
   Wscript.Echo &quot;------------------------------&quot;               &amp; vbCr &amp;_
                &quot;Win32_TimeZone instance&quot;                      &amp; vbCr &amp;_
                &quot;------------------------------&quot;               &amp; vbCr &amp;_
                &quot;Bias:&quot;    &amp; vbTab &amp; vbTab &amp; Item.Bias         &amp; vbCr &amp;_
                &quot;Caption:&quot; &amp; vbTab &amp; vbTab &amp; Item.Caption      &amp; vbCr &amp;_
                &quot;Description:&quot;     &amp; vbTab &amp; Item.Description  &amp; vbCr &amp;_
                &quot;DayLight Name:&quot;   &amp; vbTab &amp; Item.DayLightName &amp; vbCr &amp;_
                &quot;Standard Name:&quot;   &amp; vbTab &amp; Item.StandardName
Next</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Flasher]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=27593</uri>
			</author>
			<updated>2016-05-05T12:38:38Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103380#p103380</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103379#p103379" />
			<content type="html"><![CDATA[<p>Наконец то выкроил время чтобы разобраться с датами. В качестве эталона использовал Sysinternals ADExplorer.<br />ActiveTimeBias - текущий часовой пояс. В VBS нет встроенных функций для его извлечения, поэтому авторы скрипта (выше) тянут его из реестра.<br />В JS все решается на порядок проще:</p><div class="codebox"><pre><code>function GetTime(val) {
	var i8High = val.HighPart;
	var i8Low = val.LowPart;
	if (i8Low &lt; 0) i8High += 1;
	if ((i8High == 0) &amp;&amp; (i8Low == 0)) {
		return &#039;0&#039;;
	} else {
		var LargeIntegerToDate = (i8High * 4294967296 + i8Low) / 10000 + Date.UTC(1601,0,1);
		return new Date(LargeIntegerToDate).toLocaleString();
	}
}</code></pre></div><p>Так извлекаются даты из атрибутов badPasswordTime, lastLogoff, lastLogon, lastLogonTimestamp.<br />В остальных атрибутах (таких как dSCorePropagationData, msExchWhenMailboxCreated, whenChanged, whenCreated) тоже необходимо учитывать таймзону:</p><div class="codebox"><pre><code>
var a = new Date(val).valueOf();
var b = new Date().getTimezoneOffset()*60000;
return new Date(a-b).toLocaleString();</code></pre></div><p>Единственный неучтенный момент - это когда дата была создана в таймзоне, отличной от текущей. Тут мой алгоритм ошибается (в отличии от ADExplorer).<br /><a href="https://bitbucket.org/html-applications/ado-find/commits/80a98cad8210716097f736c6a859034887b8e9e2">Закомиттил</a> так как есть (замучили уже эти даты, есть и другие интересные атрибуты). Если кто предложит лучшее решение - буду благодарен.</p>]]></content>
			<author>
				<name><![CDATA[mozers]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4112</uri>
			</author>
			<updated>2016-05-05T11:41:49Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103379#p103379</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103133#p103133" />
			<content type="html"><![CDATA[<p>Сдается мне что 4294967296 - не константа. Недаром же её в примере от мелкософта из реестра выуживают</p><div class="codebox"><pre><code>Function MakeDate(oLInt)
	Set objShell = CreateObject(&quot;Wscript.Shell&quot;)
	lngBiasKey = objShell.RegRead(&quot;HKLM\System\CurrentControlSet\Control\TimeZoneInformation\ActiveTimeBias&quot;)
	If UCase(TypeName(lngBiasKey)) = &quot;LONG&quot; Then
		glngBias = lngBiasKey
	ElseIf UCase(TypeName(lngBiasKey)) = &quot;VARIANT()&quot; Then
		glngBias = 0
		For k = 0 To UBound(lngBiasKey)
			glngBias = lngBias + (lngBiasKey(k) * 256 ^ k)
		Next
	End If
	dtmDate = #1/1/1601# + (((oLInt.HighPart * (2 ^ 32)) + oLInt.LowPart) / 600000000 - glngBias) / 1440
	MakeDate = dtmDate
End Function</code></pre></div><p> Потом проверка показала, что не все атрибуты типа &#039;object&#039; и успешно обрабатываемые этим алгоритмом возвращают внятную дату. В общем - видимо придется фильтровать <span class="bbu">по имени</span> конкретные атрибуты, другие дата-&#039;object&#039;ы надо обрабатывать как то иначе...</p>]]></content>
			<author>
				<name><![CDATA[mozers]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4112</uri>
			</author>
			<updated>2016-04-27T18:22:58Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103133#p103133</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=103063#p103063" />
			<content type="html"><![CDATA[<p>Серый форум, помог, <a href="http://forum.script-coding.com/viewtopic.php?pid=6638#p6638">конвертирует object, возвращенный запросом к LDAP, в&nbsp; дату</a><br />было:<br /></p><div class="codebox"><pre><code>else if (typeof(val) == &#039;object&#039;)    aValues[j] = &#039;[object]&#039;;</code></pre></div><p>стало(надо):<br /></p><div class="codebox"><pre><code>else if (typeof(val) == &#039;object&#039;)    {
try {
 var res,intLastLogonTime = val.HighPart* (4294967296) + val.LowPart;
 res = intLastLogonTime / 10000;
 res = res - Math.abs((new Date(1601,0,1)).getTime());
 aValues[j]=new Date(res).toLocaleString()
} catch(e)
 {
  aValues[j] = &#039;[object]&#039;;
 }
}
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[badik]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=21834</uri>
			</author>
			<updated>2016-04-26T06:41:42Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=103063#p103063</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=102792#p102792" />
			<content type="html"><![CDATA[<p>2<strong>badik</strong><br />Верное предложение, принимается!<br />Еще реализовал просмотр многострочных значений, GUID-ов, фотографий пользователей, данных времени.<br />Ну и вообще поправил алгоритм - сейчас извлекается гораздо больше атрибутов.</p>]]></content>
			<author>
				<name><![CDATA[mozers]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4112</uri>
			</author>
			<updated>2016-04-21T19:42:52Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=102792#p102792</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=102737#p102737" />
			<content type="html"><![CDATA[<p>для поиска в JScript можно добавить условие поиска по displayName<br /></p><div class="codebox"><pre><code>var aFilters0 = [&quot;(cn=&quot;+str+&quot;*)&quot;, &quot;(sAMAccountName=&quot;+str+&quot;*)&quot;,&quot;(displayName=&quot;+str+&quot;*)&quot;];
</code></pre></div>]]></content>
			<author>
				<name><![CDATA[badik]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=21834</uri>
			</author>
			<updated>2016-04-20T08:20:30Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=102737#p102737</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[HTA: Active Directory Objects Finder]]></title>
			<link rel="alternate" href="https://forum.script-coding.com/viewtopic.php?pid=102714#p102714" />
			<content type="html"><![CDATA[<p>В общем то я всегда обходился консольной dsquery для поиска и Русиновичевским ADExplorer для детализации.<br />Мелкософтовский RSAT с его &quot;Центром администрирования&quot; использую крайне редко (уж больно он тяжелый).<br />А тут товарищу понадобилось находить некие атрибуты учеток которые через стандартный аплет &quot;Active Directory Users and Computers&quot; найти чрезвычайно сложно.<br />Вот тогда и была написана это HTA-шка.<br />Помимо собственно пользователей, которых можно искать как по логину так и по имени (или части его) ищет компьютеры, группы, контакты и другие объекты AD.<br />Результаты снабжены названием типа объекта и раскрашены разными цветами, так что не перепутаете.<br />Выбрав в комбобоксе с результатами конкретный объект можно просмотреть имена и значения всех его атрибутов.<br />Пока выводятся только необработанные строковые данные. В будущем планируется преобразовывать их к более наглядному виду.<br />Также в планах преобразование данных других типов, расширение критериев поиска, подключение к другоиу домену и т.д. и пр.<br />Если есть желание подключится к совместной разработке - Welcome!<br />Код старался писать максимально наглядно чтобы желающие могли использовать его в своих злостных целях.<br />Тут выкладываю самый первый вариант поскольку в нем вся работа с AD написана на vbscript, который многим кажется проще.</p><div class="codebox"><pre><code>&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv=content-type content=&quot;text-html; charset=utf-8&quot;&gt;
&lt;meta http-equiv=MSThemeCompatible content=yes&gt;
&lt;hta:application
	id=&quot;App&quot;
	applicationName=&quot;Active Directory Objects Finder&quot;
	innerBorder=&quot;no&quot;
	icon=&quot;usercpl.dll&quot;
	scroll=&quot;no&quot;
	singleInstance=&quot;yes&quot;
	version=&quot;0.0.0&quot;
	autor=&quot;mozers™&quot;
 /&gt;
&lt;style type=&quot;text/css&quot;&gt;
	* {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;}
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	document.title = App.applicationName + &#039; v.&#039; + App.version;
	window.resizeTo(900,500);

	// Добавляет новый пункт с данными заданного объекта в комбобокс
	function AddOption (sLDAP) {
		var oOption = document.createElement(&quot;option&quot;);
		oOption.value = sLDAP;
		oOU = GetObject(sLDAP);
		oOption.text = &#039;[&#039; + oOU.Class + &#039;] &#039; + oOU.cn;
		switch(oOU.Class){
			case &#039;user&#039;:     oOption.style.color = &quot;green&quot;; break;
			case &#039;computer&#039;: oOption.style.color = &quot;blue&quot;; break;
			case &#039;group&#039;:    oOption.style.color = &quot;gray&quot;; 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();
	}
&lt;/script&gt;
&lt;/head&gt;
&lt;body onload=&quot;idObjName.focus();&quot; style=&quot;width:100%;&quot;&gt;
	&lt;table style=&quot;height:100%; width:100%&quot;&gt;
		&lt;tr&gt;
			&lt;td class=&quot;top&quot;&gt;
				&lt;table style=&quot;width:100%;&quot;&gt;
					&lt;tr&gt;
						&lt;td style=&quot;width:100%;&quot;&gt;&lt;input id=&quot;idObjName&quot; onkeydown=&quot;if (event.keyCode==13) FindADObjects()&quot; type=&quot;text&quot; style=&quot;width:100%;&quot;&gt;&lt;/td&gt;
						&lt;td&gt;&lt;button onClick=&quot;FindADObjects()&quot; hidefocus&gt;&lt;b&gt;Поиск&lt;/b&gt;&lt;/button&gt;&lt;/td&gt;
					&lt;/tr&gt;
					&lt;tr&gt;
						&lt;td style=&quot;width:100%;&quot;&gt;&lt;select id=&quot;idSelResult&quot; onselect=&quot;ShowADObject()&quot; onchange=&quot;ShowADObject()&quot; style=&quot;width:100%;&quot;&gt;&lt;/select&gt;&lt;/td&gt;
						&lt;td&gt;&lt;b&gt;[&lt;span id=&quot;idCount&quot;&gt;0&lt;/span&gt;]&lt;/b&gt;&lt;/td&gt;
					&lt;/tr&gt;
				&lt;/table&gt;
				&lt;hr size=&quot;1px&quot;&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td&gt;
				&lt;div style=&quot;height:100%; width:100%; overflow-y:scroll; overflow-x:hidden;&quot;&gt;
					&lt;table id=&quot;idResult&quot; style=&quot;width:100%;&quot;&gt;&lt;/table&gt;
				&lt;/div&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;
&lt;/body&gt;
&lt;script type=&quot;text/vbscript&quot;&gt;
	&#039; Возвращает информацию о объектах Active Directory
	&#039; Входные данные: часть имени объекта (cn или sAMAccountName)
	&#039; Найденные LDAP Strigs помещает в комбобокс
	Sub GetADInfo(str)
		Set ADOConnection = CreateObject(&quot;ADODB.Connection&quot;)
		ADOConnection.Provider = &quot;ADsDSOObject&quot;
		ADOConnection.Open &quot;Active Directory Provider&quot;
		strDNSDomain = GetObject(&quot;LDAP://RootDSE&quot;).Get(&quot;defaultNamingContext&quot;)

		Set adoCommand = CreateObject(&quot;ADODB.Command&quot;)
		adoCommand.ActiveConnection = ADOConnection
		adoCommand.Properties(&quot;Page Size&quot;) = 1000
		adoCommand.Properties(&quot;Searchscope&quot;) = 2 &#039;ADS_SCOPE_SUBTREE
		adoCommand.CommandText = &quot;SELECT * FROM &#039;LDAP://&quot; &amp; strDNSDomain &amp; &quot;&#039; WHERE cn=&#039;&quot; &amp; str &amp; &quot;*&#039; OR sAMAccountName=&#039;&quot; &amp; str &amp; &quot;*&#039;&quot;
		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

	&#039; Перечисляет все свойства выбранного объекта 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

	&#039; Пробует извлечь из Obj значение c именем name
	&#039; Если получается - дополняет сторкой таблицу имясвойства - значение
	&#039; TODO: Далеко не все значения хранятся как String. Необходимо дописать обработку других типов данных.
	Sub GetProperty(obj, name)
		On Error Resume Next
		v = obj.Get(name)
		If Err.Number &lt;&gt; 0 Then Exit Sub
		AddRow name, CStr(v)
	End Sub
&lt;/script&gt;
&lt;/html&gt;</code></pre></div><p>Доработанная и обновляемая версия (уже на чистом javascript) лежит <a href="https://bitbucket.org/html-applications/ado-find"><strong>тут</strong></a>.<br />Конечно жду критики и предложений. Ради этого все и делается...</p>]]></content>
			<author>
				<name><![CDATA[mozers]]></name>
				<uri>https://forum.script-coding.com/profile.php?id=4112</uri>
			</author>
			<updated>2016-04-18T14:37:31Z</updated>
			<id>https://forum.script-coding.com/viewtopic.php?pid=102714#p102714</id>
		</entry>
</feed>
