Active Directoryグループとユーザーに基づいてZimbra Collaboration OSEでメーリングリストを作成および更新する

画像



1.著者からのいくつかの言葉



記事が更新されました。 スクリプトが変更されました。 1つのメーリングリストを更新するスクリプトが追加されました。



前回の記事へのコメントで、ADセキュリティグループに基づいたメーリングリストの自動形成に関する興味深い質問がありました。 問題があります-解決策があります。 行きましょう。



2.ソースデータ



サーバーOS :CentOS 7



OSについて
実際、CentOS7と他のシステムの違いは、パッケージをインストールするためのサーバーへのコマンドと、場合によってはいくつかのファイルの場所にあります。 作業は主にZimbraコマンドレットで実行されるため、構成の違いは最小限に抑えられます。



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 Collaboration OSEでの配布リストの形成を除いて、ドメインのライフサイクルに参加することはありません。



4. ADからデータを収集するPowerShellスクリプト



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倍にならないようにするために必要です。
  2. PoShは指定されたOUを見て、そのOUにあるユーザーグループを読み取り、それらをGetGroupsAD.txtファイルに書き込みます
  3. 受信したファイルから不要なものをすべて破棄します(PoShはすべての出力をファイルに書き込むため、コマンドの最初の出力では、最初の行はName、2番目の行はセパレーター「----」、その後グループが1つずつリストされます)、エンコードを変更します「windows-1251」からutf-8まで、別のファイルGroupsList.txtになります
  4. さらに、受信したファイルに基づいて、ファイルに含まれるグループのユーザーに関する情報が読み取られます。 ユーザー名を含むファイル(samAccountName)

    \ Usersディレクトリに配置され、グループ名で呼び出されます




4.2。 単一のグループから情報を読み取るためのスクリプト



1つのセキュリティグループのみからデータを読み取ることができるスクリプトは、基本的にメーリングリストを更新する必要があるグループの名前を入力するようユーザーに要求するブロックがあるため、以前のセキュリティグループとそれほど違いはありません。



1つのグループのみからデータを読み取る機能を備えた手動で実行する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. グループのリストに基づいてメーリングリストを1つずつ作成し、各グループにユーザーを入力します(配布リストのIDが画面に表示されます。これはDL作成時のzmprovコマンドレットの標準出力です)。 これにより、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の実装方法」シリーズの3番目の記事です。 最初の実装、LDAP認証、ADユーザーのメールボックスの自動作成については、 こちらをご覧ください 。 2つ目は、Zimbra全体のバックアップとリカバリの設定について、個別のボックスについてです。



All Articles