Crie e atualize listas de discussão no Zimbra Collaboration OSE com base em grupos e usuários do Active Directory

imagem

1. Algumas palavras do autor


Artigo atualizado. Scripts alterados. Adicionado script para atualizar uma lista de distribuição.

Nos comentários do último artigo, me fizeram uma pergunta interessante sobre a formação automática de listas de discussão com base em grupos de segurança do AD. Há um problema - há uma solução. Então vamos lá.

2. Os dados de origem


Sistema operacional do servidor : CentOS 7

Sobre o SO
De fato, a diferença entre o CentOS7 e qualquer outro sistema está apenas em comandos para o servidor instalar pacotes e, possivelmente, na localização de alguns arquivos. O trabalho é realizado principalmente com cmdlets do Zimbra, portanto as diferenças de configuração serão mínimas.

Domínio Zimbra : zimbramail.home.local
O caminho para montar as bolas no host Zimbra : / mnt / ZM /

3. Configuração


  1. Montamos a bola do Windows no nosso servidor Linux. Isso é para simplificar e automatizar a transferência de dados do Windows PowerShell para o Linux Bash. O procedimento de montagem foi descrito em um artigo anterior. Eu não vou me repetir.
  2. Criamos uma OU separada no AD, na qual criamos grupos com base nas quais as listas de discussão serão criadas no Zimbra. Nome do grupo = nome da lista de distribuição.
  3. Adicione aos grupos criados na nova UO, usuários ou grupos de segurança, com base nos quais as listas de discussão no Zimbra serão preenchidas. O script é executado recursivamente, o que significa que ele coletará todos os dados sobre usuários que estão em grupos adicionados a grupos na UO de destino. Saiba mais sobre a saída do comando Get-ADGroupMember .
  4. Crie um script para coletar dados do Active Directory.
  5. Criamos um script para adicionar listas de discussão e preenchê-las pelos usuários com base nos dados recebidos no script anterior.
  6. Aprecie.


3.1 Sobre OU


Criei a OU "ZimbraDL" na raiz do domínio e proibi-a de herdar políticas de grupo para que esses grupos permaneçam separados. Eles não participarão da vida do domínio de forma alguma, exceto pela formação de Listas de Distribuição no OSE do Zimbra Collaboration.

4. Script do PowerShell para coletar dados do AD


Script do 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 Como o script funciona


  1. Primeiro, ele verifica a existência e a exclusão do diretório de trabalho, se existir. Isso é necessário para que os dados não dobrem no processo.
  2. O PoSh examina a UO especificada, lê os grupos de usuários que estão nela e os grava no arquivo GetGroupsAD.txt
  3. Descarta qualquer coisa supérflua do arquivo recebido (o PoSh grava toda a sua saída no arquivo; portanto, na saída inicial do comando, a primeira linha é Name, a segunda linha é o separador "----" e somente depois que os grupos são listados um a um), altera a codificação de "windows-1251" para utf-8, resultando em outro arquivo GroupsList.txt
  4. Além disso, com base no arquivo recebido, são lidas informações sobre os usuários dos grupos contidos no arquivo. Arquivos contendo nomes de usuário (samAccountName)
    colocado no diretório \ Users e chamado pelo nome do grupo


4.2 Script para ler informações de um único grupo


Um script com a capacidade de ler dados de apenas um grupo de segurança não é muito diferente do anterior, basicamente porque possui um bloco solicitando ao usuário que digite o nome do grupo, com base no qual a lista de discussão precisará ser atualizada.

Script do PowerShell para execução manual, com a capacidade de ler dados de apenas um grupo
 $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. Script Bash para criar listas de discussão


Farei uma reserva sobre a cópia de arquivos de script criados no Windows
Em um artigo anterior, descrevemos um método para formatar arquivos usando o comando cat, que, quando iniciado com uma chave específica, remove todos os caracteres ilegíveis desnecessários. Link para o artigo no final do artigo.

Bash Script
 #!/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 Como o script funciona


  1. Escreva uma lista de grupos em um arquivo
  2. Verifique a existência da lista de discussão no Zimbra; se existir, exclua-a
  3. Crie listas de discussão uma a uma com base na lista de grupos, preenchendo cada um deles com usuários (o ID da lista de distribuição é exibido na tela, esta é a saída padrão do cmdlet zmprov ao criar DL). Isso verifica a existência de caixas de correio do usuário no Zimbra e, se a caixa de correio não existir, o usuário não será adicionado à lista de discussão. Obviamente, você pode criar uma nova caixa de correio para o usuário e adicioná-la à lista de discussão, mas presumo que o Zimbra autoprov funcione no modo Ansioso, e se o usuário não foi criado automaticamente, ele não terá nada a fazer no sistema.
  4. Limpar arquivos temporários
  5. Excluir diretório de trabalho

6. Conclusão


Em geral, a tarefa não foi difícil, o problema estava apenas na transferência de dados do PowerShell para o Bash. Durante muito tempo, tentei encontrar uma ferramenta para transcrever arquivos de texto com saída PoSh em um formato digerível pelo Bash. O resultado de muitos dias de pesquisa foi a função:

Função de Recodificação
 $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 } 


Talvez alguém seja útil.

7. PS:


Este é o terceiro artigo da série "Como eu implementei o Zimbra". O primeiro é sobre implementação, autorização LDAP e criação automática de caixas de correio para usuários do AD, aqui . O segundo, sobre como configurar o backup e a recuperação do Zimbra na íntegra e em caixas separadas, está aqui .

Source: https://habr.com/ru/post/pt443166/


All Articles