1

Тема: JS: Получение списка почтовых ящиков из AD

Добрый день.
Стоит задача выгрузить из AD список почтовых ящиков пользователей и групп для совершения с ними дальнейших действий. Я нашел рабочий пример на VBScript

' Программа выводит все proxyAddresses из всего дерева каталогов AD и записывает
' в файл FileName = "relay_recipients" - осторожно, файл перезаписывается каждый раз.
' запускайте из командной строки (не из FAR) командой: cscript AllAddr.vbs
' укажите свой путь до верхнего каталога в AD 
' Для запуска достаточно прав обычного пользователя.
' Скрипт работает под 2000,XP,2003



Option Explicit


Dim ArrSMTPAddr() ' динамич массив для хранения proxyAddresses
Dim intCountArrSMTPAddr  'cчетчик для динамич массив для хранения proxyAddresses
intCountArrSMTPAddr = -1
Dim FileName
Dim RelativePathFromDomainToUserContainer 
Dim arrContainer() ' массив для хранения контейнеров
Dim intCountArrContainer ' счетчик для ЗАПОЛНЕНИЯ массива хранения контейнеров
Dim intCountArrContainerREAD ' счетчик для СЧИТЫВАНИЯ массива хранения контейнеров
Dim arrUserAdsPath() ' массив для хранения полного пути к объекту пользователя
Dim intCountArrUserAdsPath ' счетчик для массива хранения контейнеров пользователей
Dim intCountArrUserAdsPathREAD ' счетчик для cчитывания массива хранения контейнеров 
intCountArrUserAdsPath = -1
intCountArrContainer = 0
intCountArrContainerREAD = 0
ReDim Preserve arrContainer(intCountArrContainerREAD) 'увеличиваем размер массива



' введите свои данные
arrContainer(intCountArrContainerREAD) = "LDAP://DC=mydomain,DC=local" ' путь до верхнего каталога в AD  
'файл куда адреса записывать
FileName = "relay_recipients" 

' далее не нужно ничего вводить


'On Error Resume Next

Function ReplaceTest(str1, patrn, replStr) ' приводим SMTP адрес к нормальному виду
  Dim regEx, retVal              ' Create variables.
  Set regEx = New RegExp            ' Create regular expression.
  regEx.Pattern = patrn            ' Set pattern.
  regEx.IgnoreCase = True            ' Make case insensitive.
  retVal = regEx.Test(str1)      ' Execute the search test.
  If retVal Then
     ReplaceTest = regEx.Replace(str1, replStr)   ' Make replacement.
  Else
     ReplaceTest = Null
  End If
  Set retVal = Nothing
End Function

Sub WriteProxyAddrToFile() 'записываем адреса из массива в файл 

    Dim f, fs, temp
WScript.Echo "  Now we are saving this array to file "
    Set fs = CreateObject("Scripting.FileSystemObject")
    Set f = fs.CreateTextFile(FileName) 
       '  f.Write "New once " & Date & "  " & Time
       For Each temp In ArrSMTPAddr
      f.Write temp & " OK"        
          f.Write Chr(13)    
          f.Write Chr(10)
       Next



End Sub


Sub SMTPAdresses(Path) ' Записываем  адреса в массив ArrSMTPAddr(intCountArrSMTPAddr)

Dim address
Dim ObjectName
Dim strTemp

  Set ObjectName = GetObject(Path)
'  WScript.Echo "ObjectName: " & ObjectName.Name 
'  WScript.Echo "ObjectClass: " & ObjectName.Class 
'  WScript.Echo "ObjectName.proxyAddresses: Type =" & TypeName(ObjectName.proxyAddresses)

  If TypeName(ObjectName.proxyAddresses) = "String" Then

'       WScript.Echo "ObjectName.proxyAddresses: " & ReplaceTest(ObjectName.proxyAddresses,"smtp:", "")
      intCountArrSMTPAddr = intCountArrSMTPAddr + 1  ' инкрементируем размер счетчика
      ReDim Preserve ArrSMTPAddr(intCountArrSMTPAddr) 'увеличиваем размер массива
      ArrSMTPAddr(intCountArrSMTPAddr) = ReplaceTest(ObjectName.proxyAddresses,"smtp:","")
     WScript.Echo "ArrSMTPAddr(" & intCountArrSMTPAddr & ")" & ArrSMTPAddr(intCountArrSMTPAddr)        
' WScript.Echo "intCountArrSMTPAddr " & intCountArrSMTPAddr

  ElseIf TypeName(ObjectName.proxyAddresses) = "Variant()" Then

     For Each address In ObjectName.proxyAddresses
    strTemp = ReplaceTest(address,"smtp:", "")    
    If NOT strTemp = "" Then      ' если функция ReplaceTest возвращает пустое значение
'          WScript.Echo "strTemp             :" & strTemp
          intCountArrSMTPAddr = intCountArrSMTPAddr + 1  ' инкрементируем размер счетчика
          ReDim Preserve ArrSMTPAddr(intCountArrSMTPAddr) 'увеличиваем размер массива
          ArrSMTPAddr(intCountArrSMTPAddr) = strTemp
     WScript.Echo "ArrSMTPAddr(" & intCountArrSMTPAddr & ")" & ArrSMTPAddr(intCountArrSMTPAddr)        
'       WScript.Echo "intCountArrSMTPAddr " & intCountArrSMTPAddr

    End If

     Next

  ElseIf TypeName(ObjectName.proxyAddresses) = "Empty" Then
    '
  Else
       WScript.Echo " Error!!! Programm can not understand type of variable ObjectName.proxyAddresses"
  End If
  Set ObjectName = Nothing

End Sub

Sub GetADsPath() 'получаем пути на всех юзеров и записываем их в массив

Dim Directory, Object

Do
WScript.Echo arrContainer(intCountArrContainerREAD)
 Set Directory = GetObject(arrContainer(intCountArrContainerREAD))

 For Each Object In Directory
 
  If Object.Class = "user" Then
     intCountArrUserAdsPath = intCountArrUserAdsPath + 1
     ReDim Preserve arrUserAdsPath(intCountArrUserAdsPath) 'увеличиваем размер массива
     arrUserAdsPath(intCountArrUserAdsPath) = Object.AdsPath
     WScript.Echo "Object.Class user: " & arrUserAdsPath(intCountArrUserAdsPath)
  ElseIf Object.Class = "group" Then
     intCountArrUserAdsPath = intCountArrUserAdsPath + 1
     ReDim Preserve arrUserAdsPath(intCountArrUserAdsPath) 'увеличиваем размер массива
     arrUserAdsPath(intCountArrUserAdsPath) = Object.AdsPath
     WScript.Echo "Object.Class group: " & arrUserAdsPath(intCountArrUserAdsPath)
  ElseIf Object.Class = "container" Then
     intCountArrContainer = intCountArrContainer + 1
     ReDim Preserve arrContainer(intCountArrContainer) 'увеличиваем размер массива
     arrContainer(intCountArrContainer) = Object.AdsPath
     WScript.Echo "Object.Class container: " & Object.Class
  ElseIf Object.Class = "organizationalUnit" Then
     intCountArrContainer = intCountArrContainer + 1
     ReDim Preserve arrContainer(intCountArrContainer) 'увеличиваем размер массива
     arrContainer(intCountArrContainer) = Object.AdsPath
     WScript.Echo "Object.Class OU: " & Object.Class
  End If

 Next
 intCountArrContainerREAD = intCountArrContainerREAD + 1
 Set  Directory = Nothing
Loop While intCountArrContainerREAD < intCountArrContainer

End Sub


Sub main()

Dim Object

GetADsPath() 'получаем пути на всех юзеров и записываем их в массив

'цикл для работы с пользователями Записываем  адреса в массив ArrSMTPAddr(intCountArrSMTPAddr)
For Each Object In arrUserAdsPath
   
     WScript.Echo "Object: " & Object
     SMTPAdresses(Object)

Next

'WriteProxyAddrToFile() 'записываем адреса из массива в файл 

End Sub

main()

и пытаюсь переписать его на JScript. Получился следующий код:

var arrSMTPAddr = new Array();        // динамич массив для хранения proxyAddresses
var intCountarrSMTPAddr;            // cчетчик для динамич массив для хранения proxyAddresses
var intCountarrSMTPAddr = -1;        //
var RelativePathFromDomainToUserContainer;
var arrContainer = new Array();        // массив для хранения контейнеров
var intCountArrContainer;            // счетчик для ЗАПОЛНЕНИЯ массива хранения контейнеров
var intCountArrContainerREAD;        // счетчик для СЧИТЫВАНИЯ массива хранения контейнеров
var arrUserAdsPath = new Array();    // массив для хранения полного пути к объекту пользователя
var intCountArrUserAdsPath;         // счетчик для массива хранения контейнеров пользователей
var intCountArrUserAdsPathREAD;        // счетчик для cчитывания массива хранения контейнеров 
var intCountArrUserAdsPath = -1;
var intCountArrContainer = 0;
var intCountArrContainerREAD = 0;

// Путь до верхнего каталога в AD  
arrContainer[intCountArrContainerREAD] = "LDAP://DC=mydomain,DC=local"; 

function debug (s){
    //WScript.Echo(s);
}

// Получаем SMTP адреса для объекта в AD
function SMTPAdresses(Path) {
    var ObjectName = GetObject(Path);
    debug( "ObjectName: " + ObjectName.Name );
    debug( "ObjectClass: " + ObjectName.Class );
    debug( "ObjectName.proxyAddresses: Type = " + typeof ObjectName.proxyAddresses );
    
    switch (typeof ObjectName.proxyAddresses){
        case "string":
            var strTemp = ObjectName.proxyAddresses.replace("smtp:", "");
            debug( "ObjectName.proxyAddresses: " + strTemp );
            intCountarrSMTPAddr += 1;
            arrSMTPAddr[intCountarrSMTPAddr] = strTemp;
            debug( "arrSMTPAddr(" + intCountarrSMTPAddr + ")" + arrSMTPAddr[intCountarrSMTPAddr]);
            debug( "intCountarrSMTPAddr " + intCountarrSMTPAddr);
            break;
        case "undefined":
            for ( var address in ObjectName.proxyAddresses ){
                var strTemp = address.replace("smtp:", "");
                if ( strTemp != "" ){
                    WScript.Echo( "strTemp             :" + strTemp);
                    intCountarrSMTPAddr += 1;
                    arrSMTPAddr[intCountarrSMTPAddr] = strTemp;
                    WScript.Echo( "arrSMTPAddr(" + intCountarrSMTPAddr + ")" + arrSMTPAddr[intCountarrSMTPAddr]);        
                    WScript.Echo( "intCountarrSMTPAddr " + intCountarrSMTPAddr );
                }
            }    
            break;
        case "unknown":
            break;
          default:
           WScript.Echo(" Error!!! Programm can not understand type of variable ObjectName.proxyAddresses");
           WScript.Quit();
           break;
      }
}

// получаем пути на всех юзеров и записываем их в массив
function GetADsPath(){
    do {
        var Directory = GetObject(arrContainer[intCountArrContainerREAD]);

        var e = new Enumerator(Directory);
        for(; !e.atEnd(); e.moveNext() ) {
            var Object = e.item();
    
              switch (Object.Class) {
                case "user":
                    intCountArrUserAdsPath += 1;
                    arrUserAdsPath[intCountArrUserAdsPath] = Object.AdsPath;
                    debug( "Object.Class user: " + arrUserAdsPath[intCountArrUserAdsPath] );
                    break;
                case "group":
                    intCountArrUserAdsPath += 1;
                    arrUserAdsPath[intCountArrUserAdsPath] = Object.AdsPath;
                    debug( "Object.Class group: " + arrUserAdsPath[intCountArrUserAdsPath] );
                    break;
                case "container":
                    intCountArrContainer += 1;
                    arrContainer[intCountArrContainer] = Object.AdsPath;
                    debug( "Object.Class container: " + Object.Class );
                    break;
                case "organizationalUnit":
                    intCountArrContainer += 1;
                    arrContainer[intCountArrContainer] = Object.AdsPath;
                    debug( "Object.Class OU: " + Object.Class );
                    break;
              }
        }
         intCountArrContainerREAD += 1;
    } while ( intCountArrContainerREAD < intCountArrContainer );
}

function main() {
    // получаем пути на всех юзеров и записываем их в массив
    GetADsPath();
    
    // цикл для работы с пользователями Записываем  адреса в массив arrSMTPAddr(intCountarrSMTPAddr)
    for ( var Object in arrUserAdsPath ) {
        debug( "Object: " + arrUserAdsPath[Object] );
        SMTPAdresses(arrUserAdsPath[Object]);
    }
    
    for ( var Object in arrSMTPAddr ) {
        WScript.Echo(Object + ": " + arrSMTPAddr[Object] );
    }
}

main();

Проблема возникла в переписывании случая

ElseIf TypeName(ObjectName.proxyAddresses) = "Variant()" Then

     For Each address In ObjectName.proxyAddresses
    strTemp = ReplaceTest(address,"smtp:", "")    
    If NOT strTemp = "" Then      ' если функция ReplaceTest возвращает пустое значение
'          WScript.Echo "strTemp             :" & strTemp
          intCountArrSMTPAddr = intCountArrSMTPAddr + 1  ' инкрементируем размер счетчика
          ReDim Preserve ArrSMTPAddr(intCountArrSMTPAddr) 'увеличиваем размер массива
          ArrSMTPAddr(intCountArrSMTPAddr) = strTemp
     WScript.Echo "ArrSMTPAddr(" & intCountArrSMTPAddr & ")" & ArrSMTPAddr(intCountArrSMTPAddr)        
'       WScript.Echo "intCountArrSMTPAddr " & intCountArrSMTPAddr

    End If

Если я правильно понял, то в VBScript'e этот случай соответствует работе с массивом. Но в JScript'е функция typeof ObjectName.proxyAddresses в данном случае выдаст "unknown" и не понятно, что с эти делать. Помогите, пожалуйста, разобраться. Хочется получить либо совет, как переписать данный блок на JScript, либо рабочий пример получения списка ящиков пользователей из AD на JS.

2

Re: JS: Получение списка почтовых ящиков из AD

хотел посмотреть, что за такие "почтовые ящики пользователей" выводит скрипт.
в строках:

' введите свои данные
arrContainer(intCountArrContainerREAD) = "LDAP://DC=mydomain,DC=local" ' путь до верхнего каталога в AD  
'файл куда адреса записывать
FileName = "relay_recipients"

определил свой домен, файл для вывода и переопределял (типа D:\relay_recipients.txt) и оставлял как выше - все одно - не могу найти после отработки скрипта нигде этого "relay_recipients"???
скрипт запускал bat-файлом:

C:\WINDOWS\system32\cscript.exe "D:\SCRIPTS\ADSI\AllAddr.vbs"
pause

где AllAddr.vbs - скопированный код, pause - чтобы видеть, что что-то работало. В окне интерпритатора видно, что скрипт "работал", но файла никакого нету.
Где этот адрес почтового ящика в AD находиться? Закладка "Общие" поле "Эл. почта:" там что ли?

3 (изменено: smaharbA, 2012-10-02 20:15:50)

Re: JS: Получение списка почтовых ящиков из AD

код довольно таки мягко говоря странен (не нужна там псевдорекурсия), но лениво писать, тупо переделан вбс-ный код тут:

var ArrSMTPAddr=new Array();// ' динамич массив для хранения proxyAddresses
var intCountArrSMTPAddr = -1;
var arrContainer=new Array();// ' массив для хранения контейнеров
var arrUserAdsPath=new Array();// ' массив для хранения полного пути к объекту пользователя
var intCountArrUserAdsPath = -1;
var intCountArrContainer = 0;
var intCountArrContainerREAD = 0;
arrContainer[intCountArrContainerREAD] = "LDAP://DC=n-d,DC=ru";// ' путь до верхнего каталога в AD  
var FileName = "relay_recipients";


function SMTPAdresses(Path) // ' Записываем  адреса в массив ArrSMTPAddr(intCountArrSMTPAddr)
{

	var ObjectName = GetObject(Path);
	var x;
	if (ObjectName.proxyAddresses  != undefined)
		x=Path  + " => " + (ObjectName.proxyAddresses.toArray ?  ObjectName.proxyAddresses.toArray().toString() : ObjectName.proxyAddresses);
	if (ObjectName.mail != undefined)
		x = (x ? x : Path) + " => " + ObjectName.mail;
	if (x) WScript.Echo(x);
}

function GetADsPath() //'получаем пути на всех юзеров и записываем их в массив
{
	do
	{
		var Directory = GetObject(arrContainer[intCountArrContainerREAD]);
		var e=new Enumerator(Directory);
		for (;!e.atEnd();e.moveNext())
		{
			var Object=e.item();
			if ((/user|group/gi).test(Object.Class))
			{
				intCountArrUserAdsPath = intCountArrUserAdsPath + 1;
				arrUserAdsPath[intCountArrUserAdsPath] = Object.AdsPath;
			}
			else if ((/container|organizationalUnit/gi).test(Object.Class))
			{
				intCountArrContainer = intCountArrContainer + 1;
				arrContainer[intCountArrContainer] = Object.AdsPath;
			}
		}
		intCountArrContainerREAD = intCountArrContainerREAD + 1;
	} while (intCountArrContainerREAD < intCountArrContainer);
}

function main()
{
	GetADsPath();// 'получаем пути на всех юзеров и записываем их в массив

	for(i=0;i<arrUserAdsPath.length;i++)
		SMTPAdresses(arrUserAdsPath[i])
		//WriteProxyAddrToFile(); 'записываем адреса из массива в файл 
}

main();
Я конечно далек от мысли... (с)

4

Re: JS: Получение списка почтовых ящиков из AD

im2002 - этот атрибут виден только при наличие ексченжа, иначе его надо разрешить и редактировать в адсиедите

http://technet.microsoft.com/ru-ru/library/cc720282%28v=ws.10%29.aspx

Я конечно далек от мысли... (с)

5

Re: JS: Получение списка почтовых ящиков из AD

поправьте, если нужен и обычный атрибут mail

function SMTPAdresses(Path) // ' Записываем  адреса в массив ArrSMTPAddr(intCountArrSMTPAddr)
{

    var ObjectName = GetObject(Path);
    var x;
    if (ObjectName.proxyAddresses  != undefined)
        x=Path  + " => " + (ObjectName.proxyAddresses.toArray ?  ObjectName.proxyAddresses.toArray().toString() : ObjectName.proxyAddresses);
    if (ObjectName.mail != undefined)
        x = (x ? x : Path) + " => " + ObjectName.mail;
    if (x) WScript.Echo(x);
}
Я конечно далек от мысли... (с)

6 (изменено: Aaroniero, 2012-10-24 17:03:06)

Re: JS: Получение списка почтовых ящиков из AD

Большое спасибо. Задача решена. Вот получившийся скрипт.

var arrSMTPAddr = new Array();		// Массив для хранения адресов
var arrContainer = new Array();		// Массив для хранения контейнеров
var arrUserAdsPath = new Array();	// Массив для хранения полного пути к объекту пользователя
var intCountArrUserAdsPath = -1;
var intCountArrContainer = 0;
var intCountArrContainerREAD = 0;
arrContainer[intCountArrContainerREAD] = "LDAP://DC=mydomain,DC=local"; // Путь до верхнего каталога в AD  
var FileName = "relay_recipients.txt"; // Файл для сохранения результата

// Выкидываем все дубликаты почтовых ящиков и то что ими не является
function ClearArray()
{
	arrSMTPAddr.sort();
	var arrTmp = new Array();
	var last="";
	for (i=0;i<arrSMTPAddr.length;i++) {
		if ( arrSMTPAddr[i].match(/^[\w-.]+@[\w-.]+$/) && last != arrSMTPAddr[i] ) {
			last = arrSMTPAddr[i];
			arrTmp.push(last);
		}
	}
	arrSMTPAddr = arrTmp;
}

// Записываем адреса из массива в файл
function WriteProxyAddrToFile()
{
	var fso = new ActiveXObject("scripting.filesystemobject");
	var f = fso.CreateTextFile(FileName,true);
	for (i=0;i<arrSMTPAddr.length;i++)
		f.WriteLine(arrSMTPAddr[i]);
	f.Close();
}

// Получаем адрес пользователя и записываем в массив
function SMTPAdresses(Path)
{
	var ObjectName = GetObject(Path);
	if (ObjectName.proxyAddresses  != undefined){
		var y = (ObjectName.proxyAddresses.toArray ?  ObjectName.proxyAddresses.toArray().toString() : ObjectName.proxyAddresses).toLowerCase().replace(/smtp:/g,"");
		arrSMTPAddr = arrSMTPAddr.concat(y.split(","));
	}
	if (ObjectName.mail != undefined){
		var y = ObjectName.mail.toLowerCase();
		arrSMTPAddr.push(y);
	}
}

// Получаем пути на всех юзеров из AD и записываем их в массив
function GetADsPath()
{
	do
	{
		var Directory = GetObject(arrContainer[intCountArrContainerREAD]);
		var e=new Enumerator(Directory);
		for (;!e.atEnd();e.moveNext())
		{
			var Object=e.item();
			if ((/user|group|publicfolder/gi).test(Object.Class))
			{
				intCountArrUserAdsPath += 1;
				arrUserAdsPath[intCountArrUserAdsPath] = Object.AdsPath;
			}
			else if ((/container|organizationalUnit/gi).test(Object.Class))
			{
				intCountArrContainer += 1;
				arrContainer[intCountArrContainer] = Object.AdsPath;
			}
		}
		intCountArrContainerREAD += 1;
	} while (intCountArrContainerREAD <= intCountArrContainer);
}
 
function main()
{
	// Получаем пути на всех юзеров и записываем их в массив
	GetADsPath();
	
	for(i=0;i<arrUserAdsPath.length;i++)
		SMTPAdresses(arrUserAdsPath[i]);
	
	// Вычищаем массив от дубликатов и некорректных записей
	ClearArray();
	
	// Записываем адреса из массива в файл 
	// WriteProxyAddrToFile(); 
}
 
main();

7

Re: JS: Получение списка почтовых ящиков из AD

Дополнил скрипт. Добавил поддержку PublicFolder.