根据Active Directory组和用户在Zimbra Collaboration OSE中创建和更新邮件列表

图片

1.作者的几句话


文章已更新。 脚本已更改。 添加了脚本来更新一个邮件列表。

在上一篇文章的评论中,有人问我有关基于AD安全组自动形成邮件列表的有趣问题。 有一个问题-有一个解决方案。 所以走吧

2.源数据


服务器操作系统 :CentOS 7

关于操作系统
实际上,CentOS7与任何其他系统之间的区别仅在于向服务器发送命令以安装软件包,并且可能还有一些文件的位置。 该工作主要是使用Zimbra cmdlet进行的,因此配置差异将很小。

Zimbra网域 :zimbramail.home.local
将球安装在Zimbra主机上的路径 :/ mnt / ZM /

3.设定


  1. 我们将Windows球安装到我们的Linux服务器上。 这是为了简化和自动化从Windows PowerShell到Linux Bash的数据传输。 上一篇文章中介绍了安装过程。 我不会重复自己。
  2. 我们在AD中创建了一个单独的OU,在其中我们根据将在Zimbra中创建邮件列表的基础创建组。 组名称=通讯组列表名称。
  3. 我们将添加到新OU中创建的组,用户或安全组中,以此为基础将填充Zimbra中的邮件列表。 该脚本以递归方式运行,这意味着它将收集与组中用户有关的所有数据,这些用户将添加到目标OU中的组中。 了解有关Get-ADGroupMember命令的输出的更多信息。
  4. 创建一个脚本以从Active Directory收集数据。
  5. 我们创建一个脚本,用于添加邮件列表,并根据上一个脚本中接收到的数据由用户填写。
  6. 好好享受


3.1。 关于OU


我在域的根部创建了OU“ ZimbraDL”,并禁止其继承组策略,以便这些组保持独立。 除了在Zimbra协作OSE中形成分发列表之外,他们不会以任何方式参与该域的工作。

4. PowerShell脚本从AD收集数据


PowerShell脚本
$Path = "C:\ZM\ZimbraDL" $enc = [system.text.encoding] function ReCode ( $f, $t, $line ) { $cp1 = $enc::getencoding( $f ) $cp2 = $enc::getencoding( $t ) $inputbytes = $enc::convert( $cp1, $cp2, $cp2.getbytes( $line )) $outputstring = $cp2.getstring( $inputbytes ) $outputstring | add-content $OutputFile } #  if(test-path $Path) { Remove-Item $Path -Recurse -Force } #   if(!(Test-Path $Path)) { New-Item -ItemType Directory -Force -Path $Path } if(!(Test-Path $Path\Groups)) { New-Item -ItemType Directory -Force -Path $Path\Groups } if(!(Test-Path $Path\Users)) { New-Item -ItemType Directory -Force -Path $Path\Users } if(!(Test-Path $Path\UsersTemp)) { New-Item -ItemType Directory -Force -Path $Path\UsersTemp } #   Import-Module ActiveDirectory Get-AdGroup -filter * -SearchBase "OU=ZimbraDL,DC=home,DC=local" | select samaccountname | Out-File $Path\Groups\GetGroupsAD.txt #   (Get-Content "$Path\Groups\GetGroupsAD.txt") -notmatch "samaccountname" | where {$_ -ne ""} | where {$_ -ne "--"} | Where-Object {$_ -notmatch '-'} | out-file "$Path\Groups\GetGroupsAD.txt" $File = @(Get-Content $Path\Groups\GetGroupsAD.txt) foreach ($File1 in $File) { $string=$File1.TrimStart('"') $string=$string.TrimEnd('"') $string=$string.TrimStart(' ') $string=$string.TrimEnd(' ') | Out-File $Path\Groups\GroupsListTemp.txt -Append } #   Remove-Item $Path\Groups\GetGroupsAD.txt -Force $InputFile = gc $Path\Groups\GroupsListTemp.txt $OutputFile = "$Path\Groups\GroupsList.txt" #  foreach ($line in $InputFile) { ReCode -f "windows-1251" -t "utf-8" $line } #   Remove-Item $Path\Groups\GroupsListTemp.txt -Force #        $GroupName = @(Get-Content $Path\Groups\GroupsList.txt) Foreach ($Group in $GroupName) { Get-ADGroupMember $Group -recursive | ft SamAccountName | out-file "$Path\UsersTemp\$Group.txt" -Append (get-content "$Path\UsersTemp\$Group.txt") -notmatch "Name" | where {$_ -ne ""} | where {$_ -ne "--"} | Where-Object {$_ -notmatch '-'} | out-file "$Path\UsersTemp\$Group.txt" $File=@(Get-Content $Path\UsersTemp\$Group.txt) foreach ($File1 in $File) { $string=$File1.TrimStart('"') $string=$string.TrimEnd('"') $string=$string.TrimStart(' ') $string=$String.TrimEnd(' ') | Out-File "$Path\UsersTemp\$Group" -Append } $InputFile = gc $Path\UsersTemp\$Group $OutputFile = "$Path\Users\$Group" #  foreach ($line in $InputFile) { ReCode -f "windows-1251" -t "utf-8" $line } } #    Remove-Item "$Path\UsersTemp\" -Recurse -Force Remove-Item "$Path\Groups" -Recurse -Force 


4.1。 脚本如何工作


  1. 首先,它检查工作目录是否存在和删除。 这是必要的,以便在此过程中数据不会加倍。
  2. PoSh查看指定的OU,读取其中的用户组,然后将它们写入GetGroupsAD.txt文件。
  3. 丢弃接收到的文件中多余的所有内容(PoSh将其所有输出都写入文件,因此在命令的初始输出中,第一行是Name,第二行是分隔符“ ----”,然后才逐一列出这些组),然后更改编码从“ windows-1251”到utf-8,导致另一个文件GroupsList.txt
  4. 此外,基于接收到的文件,读取关于文件中包含的组的用户的信息。 包含用户名(samAccountName)的文件
    放在\ Users目录中,并按组名调用


4.2。 用于从单个组读取信息的脚本


能够仅从一个安全组读取数据的脚本与上一个安全脚本没有太大不同,主要是因为该脚本有一个块,要求用户输入该组的名称,然后根据该名称来更新邮件列表。

可以手动运行的PowerShell脚本,仅能读取一组数据
 $Path = "C:\ZM\ZimbraDL" $enc = [system.text.encoding] function ReCode ( $f, $t, $line ) { $cp1 = $enc::getencoding( $f ) $cp2 = $enc::getencoding( $t ) $inputbytes = $enc::convert( $cp1, $cp2, $cp2.getbytes( $line )) $outputstring = $cp2.getstring( $inputbytes ) $outputstring | add-content $OutputFile } #  if(test-path $Path) { Remove-Item $Path -Recurse -Force } #   if(!(test-path $Path)) { New-Item -ItemType Directory -Force -Path $Path } if(!(Test-Path $Path\Groups)) { New-Item -ItemType Directory -Force -Path $Path\Groups } if(!(Test-Path $Path\Users)) { New-Item -ItemType Directory -Force -Path $Path\Users } if(!(Test-Path $Path\UsersTemp)) { New-Item -ItemType Directory -Force -Path $Path\UsersTemp } #   Import-Module ActiveDirectory $Groupname = Read-Host '  ,   ,  ALL     ' If ($Groupname -eq "ALL") { Get-AdGroup -filter * -SearchBase "OU=ZimbraDL,DC=home,DC=local" | select samaccountname | Out-File $path\Groups\GetGroupsAD.txt } Else { $Groupname > "$Path\Groups\GetGroupsAD.txt" } #   (Get-Content "$Path\Groups\GetGroupsAD.txt") -notmatch "samaccountname" | where {$_ -ne ""} | where {$_ -ne "--"} | Where-Object {$_ -notmatch '-'} | out-file "$Path\Groups\GetGroupsAD.txt" $File = @(Get-Content $Path\Groups\GetGroupsAD.txt) foreach ($File1 in $File) { $string=$File1.TrimStart('"') $string=$string.TrimEnd('"') $string=$string.TrimStart(' ') $string=$string.TrimEnd(' ') | Out-File $Path\Groups\GroupsListTemp.txt -Append } Remove-Item $Path\Groups\GetGroupsAD.txt -Force $InputFile = gc $Path\Groups\GroupsListTemp.txt $OutputFile = "$Path\Groups\GroupsList.txt" foreach ($line in $InputFile) { ReCode -f "windows-1251" -t "utf-8" $line } Remove-Item $Path\Groups\GroupsListTemp.txt -Force #        $GroupName = @(Get-Content $Path\Groups\GroupsList.txt) Foreach ($Group in $GroupName) { Get-ADGroupMember $Group -recursive | ft SamAccountName | out-file "$Path\UsersTemp\$Group.txt" -Append (get-content "$Path\UsersTemp\$Group.txt") -notmatch "Name" | where {$_ -ne ""} | where {$_ -ne "--"} | Where-Object {$_ -notmatch '-'} | out-file "$Path\UsersTemp\$Group.txt" $File=@(Get-Content $Path\UsersTemp\$Group.txt) foreach ($File1 in $File) { $string=$File1.TrimStart('"') $string=$string.TrimEnd('"') $string=$string.TrimStart(' ') $string=$String.TrimEnd(' ') | Out-File "$Path\UsersTemp\$Group" -Append } $InputFile = gc $Path\UsersTemp\$Group $OutputFile = "$Path\Users\$Group" foreach ($line in $InputFile) { ReCode -f "windows-1251" -t "utf-8" $line } } Remove-Item "$Path\UsersTemp\" -Recurse -Force Remove-Item "$Path\Groups" -Recurse -Force 



5. Bash脚本创建邮件列表


我将保留有关复制Windows下创建的脚本文件的保留意见
在上一篇文章中,我们描述了一种使用cat命令格式化文件的方法,当使用特定键启动该命令时,它将删除所有不必要的不​​可读字符。 链接到文章末尾。

Bash脚本
 #!/bin/bash #  #    Path="/mnt/ZM/ZimbraDL" #  Zimbra Domain="zimbramail.home.local" #   zmprov zmprov="/opt/zimbra/bin/zmprov" #  - log="/mnt/ZM/DLlog.txt" #       DLnames="/mnt/ZM/DLnames" #       UserNames="/mnt/ZM/Usernames" #   echo "  ..." ls $Path/Users > $DLnames if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo echo -en "ls directory for Groups correct $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "ls directory for Groups INcorrect $(date +%T)\n" >> $log fi #   echo "   " for DLname in $( cat $DLnames); do #    echo "    $DLname..." Result=$($zmprov gdl $DLname@$Domain) if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo echo -en "DL $DLname exist $(date +%T)\n" >> $log #   echo -en "Start deleting DL for group $DLname $(date +%T)\n" >> $log echo "   $DLname..." $zmprov ddl $DLname@$Domain if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo echo -en "DL for group $DLname is deleted in $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "DL for group $DLname is NOT deleted in $(date +%T)\n" >> $log fi else echo -n "$(tput hpa $(tput cols))$(tput cub 6)[FAIL]" echo echo -en "DL $DLname not exist! $(date +%T)\n" >> $log fi done for DLname in $( cat $DLnames); do #   echo -en "Start create DL for group $DLname $(date +%T)\n" >> $log echo "     AD $DLname..." $zmprov cdl $DLname@$Domain if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo echo -en "DL for group $DLname is created in $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "DL for group $DLname is NOT created in $(date +%T)\n" >> $log fi #   echo "  " for UserName in $( cat $Path/Users/$DLname); do echo "     $UserName..." Result=$($zmprov gmi $UserName@$Domain) if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo echo -en "MilBox for user $UserName exist $(date +%T)\n" >> $log echo "  $UserName    $DLname@$Domain..." $zmprov adlm $DLname@$Domain $UserName@$Domain if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6) [OK]" echo echo -en "User $UserName added in $DLname@$Domain correctly in $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "DL for group $DLname is NOT created in $(date +%T)\n" >> $log fi else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "MilBox for user $UserName is NOT exist $(date +%T)\n" >> $log fi done done #   echo "  " echo "    ..." echo -n > $DLnames if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo echo -en "File $DLnames was successfull cleared in $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "File $DLnames was NOT cleared in $(date +%T)\n" >> $log fi # ,      echo "   $Path    ..." rm -rf $Path if [ $? -eq 0 ]; then echo -n "$(tput hpa $(tput cols))$(tput cub 6)[OK]" echo echo -en "Directory $Path was seccessfull deleted in $(date +%T)\n" >> $log else echo -n "$(tput hpa $(tput cols))$(tput cub 6) [FAIL]" echo echo -en "Directory $Path was NOT deleted in $(date +%T)\n" >> $log fi #  -      echo -en "Job complete in $(date +%T)\n" >> $log echo -en "____________________________________\n" >> $log 


5.1。 脚本如何工作


  1. 将组列表写入文件
  2. 检查Zimbra中邮件列表的存在;如果存在,则将其删除
  3. 根据组列表一个一个地创建邮件列表,并用用户填充每个列表(分发列表的ID显示在屏幕上,这是创建DL时zmprov cmdlet的标准输出)。 这将检查Zimbra中用户邮箱的存在,如果该邮箱不存在,则不会将用户添加到邮件列表中。 当然,您可以为该用户创建一个新邮箱并将其添加到邮件列表中,但是我假设Zimbra autoprov在Eager模式下工作,并且如果该用户不是自动创建的,则他在系统中无事可做
  4. 清除临时文件
  5. 删除工作目录

6.结论


通常,任务并不困难,问题仅在于将数据从PowerShell传输到Bash。 很长时间以来,我一直试图找到一种工具,用于将PoSh输出的文本文件转录为Bash可消化的形式。 数天的搜索结果是以下功能:

编码功能
 $InputFile = gc File1.txt $OutputFile = "File2.txt" $enc = [system.text.encoding] function ReCode ( $f, $t, $line ) { $cp1 = $enc::getencoding( $f ) $cp2 = $enc::getencoding( $t ) $inputbytes = $enc::convert( $cp1, $cp2, $cp2.getbytes( $line )) $outputstring = $cp2.getstring( $inputbytes ) $outputstring | add-content $OutputFile } foreach ($line in $InputFile) { ReCode -f "windows-1251" -t "utf-8" $line } 


也许有人会有用。

7. PS:


这是“我如何实现Zimbra”系列的第三篇文章。 第一个是关于实现,LDAP授权和为AD用户自动创建邮箱的信息, 就在这里 。 第二篇文章是关于在整个Zimbra文件夹中分别设置备份和恢复的。

Source: https://habr.com/ru/post/zh-CN443166/


All Articles