Как стать автором
Обновить

Создание и обновление списков рассылки в Zimbra Collaboration OSE на основе групп и пользователей Active Directory

Время на прочтение 10 мин
Количество просмотров 11K
Всего голосов 11: ↑11 и ↓0 +11
Комментарии 6

Комментарии 6

$groups = Get-AdGroup -filter * -SearchBase "OU=ZimbraDL,DC=home,DC=local"
foreach ($group in $groups) {$groupname = $group.name; get-adgroupmember $groupname | select samaccountname | export-csv -LiteralPath $path\$groupname.csv -Encoding utf8 -Delimiter ';' -NoTypeInformation -Force}

С парсингом csv под bash проблем быть не должно
При использовании csv проблема не рашается. При парсинге башем все так же либо чистится файл, либо остаются «непечатные символы». Я уже пробовал этот вариант.
У меня заработала только вот такая конструкция:
$file = gc file.txt
$enc = [system.text.encoding]
function ReCode ( $f, $t, $string ) {
    $cp1          = $enc::getencoding( $f )
    $cp2          = $enc::getencoding( $t )
    $inputbytes   = $enc::convert( $cp1, $cp2, $cp2.getbytes( $string ))
    $outputstring = $cp2.getstring( $inputbytes )
    $outputstring | add-content file1.txt   
}
foreach ($string in $file) {
    ReCode-f "windows-1251" -t "utf-8" $string
}

И сегодня-завтра переделаю статью + прикручу возможность обновления списков рассылки по одному, чтобы все разом не лопатить.
Мне кажется что PowerShell и передача списка через шару это лишнее. Почему нельзя сразу из линукс конектится в домен и получать список групп и членов группы? Bash не всесилен, но Python и Perl вполне могут в ad ходить за инфой.
Я не владею Питоном или Перлом. Да, можно и так сделать, конечно, и это будет правильнее даже. Но я не умею. А изучать языки ради 2х скриптов — дело такое…
Если Вы можете — сделайте, напишите об этом пост. Ну или я могу добавить ваши скрипты с вашим копирайтом в эту статью.
немного переделал скрипт, исключил повершел (заменил на идущий с Zimbra ldapsearch). Так же исключил удаление и пересоздание групп рассылки.
пояснения:
в функции searchgroupsAD эта часть необходима, так как у меня в AD все группы рассылки начинаются с mail_имяГруппыРассылки поэтому mail_ убираем
tr '_' ' ' | 
awk '{print $2}' |


скрипт:
скрипт:
#!/bin/bash
#
#1. Определение переменных
#
#1.1 Общие переменные
#Путь к рабочему каталогу
path="/mnt/zimbra/list-sync"
#Временная метка
timestamp=`date +%F-%H-%M`
#путь к временным файлам
tmp_dir=$path/tmp
#путь к файлам логов
log_dir=$path/log
#имя лог-файла
log=$log_dir/grouplog_$timestamp.txt
#путь ко временному файлу со списком групп
glname=$tmp_dir/glname
#Путь к файлу со списком команд на пакетное выполнение утилитой zmprov
zmcmdfile=$tmp_dir/zmcmdfile
#путь ко временным файлам со списком пользователей в группах рассылки
groupuser=$tmp_dir/group
#отправка почты
mutt="/usr/bin/mutt"

#
#1.2 переменные сервера zimbra
#имя домена Zimbra
domain="test.ru"
#путь к командлету zmprov
zmprov="/opt/zimbra/bin/zmprov"
# Файл пакетной загрузки изменений в 

#1.3 переменные доступа к AD по LDAP
#LDAP search
ldapsearch=/opt/zimbra/common/bin/ldapsearch
# Подключение к серверу (либо сервер, либо домен (если больше одного сервера))
ldap_server="ldap://test.local:389"
#Базовая OU поиска
basedn="DC=test,DC=local"
#OU поиска групп рассылки
groupdn="OU=mailgroup,DC=test,DC=local"
#Пользователь и пароль для доступа к AD по LDAP
binddn="CN=zimbra,CN=Users,DC=test,DC=local"
bindpw="qwe123" #user password 
#какие поля данных ищем (логин, почту и поле с несовпадающей с логином почтой для алиаса и подписи)
fields="sAMAccountName mail extensionAttribute1"
#конец блока переменных

#Начинаем обработку

#Функции обработки
#Запись ошибки в лог
function err_log()
{
if [ $1 -eq 0 ]; then
		#echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]"
		#echo
		echo $2" [Ok]"  >> $log
	else
		#echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]"
		#echo
		echo  $2" [Fail]" >> $log
	fi
}

#Проверка существования каталога
function if_path ()
{
	#Если каталог не существует то создаем его
	if [ ! -d $1 ]; then
	#Создание каталога для обработки
	echo "Создание каталога $1..." >> $log
	mkdir -p $1
	err_log $? "Проверка каталога $1"
	
else
	echo "Каталог обработки $1 существует" >> $log	
fi
}

#Запись в файл списка групп из AD
function searchgroupsAD()
{
	# Убираем первую часть разделителя группы
	echo "Запись списка групп рассылки из AD..." >> $log
	$ldapsearch -x -o ldif-wrap=no -H $ldap_server -D $binddn -w $bindpw -b $groupdn sAMAccountName | 
	grep sAMAccountName | 
	egrep -v '^#|^$' | 
	awk '{print $2}' |
	tr '_' ' ' | 
	awk '{print $2}' |
	sort > $glname.ad
	echo "Found (Найдено) "`cat $glname.ad | wc -l`" Group in AD (групп в AD)" >> $log
}

#Запись в файл списка групп рассылки из zimbra 
function searchgroupzimbra()
{
	echo "Запись списка групп рассылки из zimbra..." >> $log
	$zmprov gadl $domain |  
	sed 's/@.*//g' | 
	sort > $glname.zim
	echo "Found (Найдено) "`cat $glname.zim | wc -l`" Group in Zimbra (групп в Zimbra)" >> $log
}

#Заполнение файла списка группы пользователями AD
function user-group-AD()
{
	#Список пользователей AD
	$ldapsearch -x -o ldif-wrap=no -H $ldap_server -D $binddn -w $bindpw -b $groupdn  "(sAMAccountName=mail_$1)" member | 
	grep member | 
	egrep -v '^#|^$' | 
	awk '{print $2}' | 
	sed -r 's/CN=//' | 
	awk '{split ($0, a, ","); print a[1]}' | 
	sort > $groupuser/$1.ad	
	echo "Found (Найдено) "`cat $groupuser/$1.ad | wc -l`" users AD in group $1 (пользователей AD в группе $1)" >> $log
}

#Заполнение файла списка группы пользователями Zimbra
function user-group-zim()
{
	#Создание списков пользователей Zimbra
	$zmprov gdlm $1@$domain | 
	sed 1,3d | 
	sed 's/@.*//g' | 
	sort > $groupuser/$1.zim
	echo "Found (Найдено) "`cat $groupuser/$1.zim | wc -l`" users Zimbra in group $1 (пользователей Zimbra в группе $1)" >> $log
	
}

function diff-user()
{
	diff -u -i $groupuser/$1.zim $groupuser/$1.ad | sed 1,3d > $groupuser/$1.diff
	#ifdif=`cat $groupuser/$1.diff`
	#проверяем, что файл не пустой
	if [ -s $groupuser/$1.diff ];
	then
		for i in $( grep -v @ $groupuser/$1.diff );
		do
			#Проверяем какое действие - удаление или добавление
			cha=`echo $i | cut -c -1`
			#удаление из списка рассылки
			if [ "$cha" == "-" ];
			then 
				deluser=`echo $i | cut -c 2-`
				echo "rdlm $1@$domain $deluser@$domain" >> $zmcmdfile
				echo "Удаляем пользователя $deluser из списка $1" >> $log
				echo "Пользователь $deluser удален из списка $1" >> $tmp_dir/send.txt
			fi
			#Добавление пользователя
			if [ "$cha" == "+" ];
			then 
				adduser=`echo $i | cut -c 2-`
				echo "adlm $1@$domain $adduser@$domain" >> $zmcmdfile
				echo "Добавляем пользователя $adduser в список $1" >> $log
				echo "Пользователь $adduser добавлен в список $1" >> $tmp_dir/send.txt
			fi
		done
	fi
}

#добавление в пакетный файл команды создания списка рассылок
function addcmdlist()
{
	# Добавляем в файл команды на создание новых списков рассылки в zimbra
	# проверяем наличие первой строки
	iflist=`grep ^+ $glname.diff | sed '1!d' | cut -c 2-`
	#проверяем, что файл не пустой
	if  [ -n $iflist ];
	then
		for group in $(grep ^+ $glname.diff | cut -c 2-);
		do
			echo "cdl "$group@$domain >> $zmcmdfile 
			echo "Добавляем списк рассылки $group" >> $log
			echo "Список рассылки $group добавлен" >> $tmp_dir/send.txt
		done
	fi
}

#функция удаления группы рассылки (см addcmdlist с заменой в цикле grep "+" на grep "-"
#и строки "cdl "$group@$domain  на "rdl "$group@$domain 
#d нашем случае только отправка уведомления админу
function delcmdlist()
{
	# Добавляем в файл команды на создание новых списков рассылки в zimbra
	iflist=`grep ^- $glname.diff | cut -c 2-`
	#проверяем, что файл не пустой
	if  [ -n $iflist ];
	then
		for group in $(grep ^- $glname.diff | cut -c 2-);
		do
			# Если надо удалить группу, то раскоментируем строку ниже, я просто посылаю уведомление администратору
			#echo "cdl "$group@$domain >> $zmcmdfile 
			echo "Удаляем списк рассылки $group" >> $log
			echo "Список рассылки $group помечен на удаление!!! проверьте и удалите самостоятельно!" >> $tmp_dir/send.txt
		done
	fi
}

#Создание файлов с именами групп списков рассылки для синхронизации
function filesgroup()
{
	#Выбираем только новые и существующие группы
	# группы на удаление обрабатываем отдельно
	for group in $( cat $glname.ad );
	do
		echo "Создание файла со списком пользователей группы "$group >> $log
		#Очищаем или создаем списки группа-пользователь
		:> $groupuser/$group.ad
		:> $groupuser/$group.zim
		:> $groupuser/$group.diff
		user-group-AD $group
		user-group-zim $group
		diff-user $group
		
	done
}


#Выполнение скрипта
#2.Проверка существования каталогов
#Корневой каталог обработки
if_path $path
#Каталог временных файлов
if_path $tmp_dir
#Каталог лог-файла
if_path $log_dir
#Каталог со списком групп
if_path $groupuser

#Очищаем файл со списком команд на пакетное выполнение утилитой zmprov
:> $zmcmdfile
:> $tmp_dir/send.txt
#3.Создаем список групп рассылки из AD 
searchgroupsAD

#4.Создаем список существующих в zimbra групп рассылки
searchgroupzimbra

#5.Сравниваем оба списка групп рассылки
diff -u -i $glname.zim $glname.ad | sed 1,3d > $glname.diff

#8. Создаем новые группы рассылки в zimbra
addcmdlist
delcmdlist

#6. Создаем список пользователей в группах рассылки AD (новые и существующие)
#7. Создаем список пользователей в существующих группах рассылки zimbra
#9. Поочередно сравниваем пользователей в группах рассылки и создаем список на модификацию (добавление и удаление пользователей из групп рассылки zimbra)
filesgroup


$zmprov -f $zmcmdfile
echo "Файл пакетного выполнения команд:" >> $log
cat $zmcmdfile >> $log
#Отправляем письмо с изменениями админу (если они есть)
if [ -s $tmp_dir/send.txt ];
then
	$mutt  -s "Изменение списков рассылки на $timestamp" admins@test.ru -a $log < $tmp_dir/send.txt
fi

#Удаляем временные файлы и каталоги
rm -R -f $tmp_dir


Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории