Restreindre les listes de distribution dans Exchange 2010

Dans cet article, je vais expliquer comment limiter les usages des listes de distribution dans Exchange 2010 :

  • implémenter un processus de modération ;
  • limiter qui peut émettre vers la liste de distribution ;
  • cacher qui est membre de la liste de distribution.

Afin de mettre en place une modération, il suffit de se rendre dans les propriétés de la liste de distribution dans Exchange, puis Mail Flow Settings, et Message Moderation.

En cochant la case, il devient possible d'ajouter des modérateurs ; ces derniers recevront une notification leur demandant de valider ou non l'envoi du mail à la liste de distribution. Il est possible d'ajouter cependant des exceptions dans la deuxième liste.

Moins flexible et plus directe, la possibilité de simplement refuser l'envoi depuis n'importe quelle adresse sauf exceptions existe. Cela se configure dans la fenêtre Message Delivery Restrictions.

Ici, on peut donc sélectionner uniquement les comptes qui ont le droit d'utiliser cette liste de distribution. Par exemple, dans le cadre d'une liste de distribution contenant tous les salariés de la société qui a pour but de relayer une communication officielle, on peut donc sélectionner les membres du service communication et donc empêcher n'importe quel utilisateur d'émettre à tous les salariés. A noter qu'il est également possible de spécifier ici des boîtes génériques : l'utilisateur doit configurer son client de messagerie pour envoyer en tant que cette boîte générique, et par essence, avoir les droits SendAs côté Exchange sur cette boîte générique. D'autre part, on peut empêcher un expéditeur non connu du serveur Exchange d'émettre vers la liste de distribution en cochant Require that all senders are authenticated, typiquement un membre externe à la société.

Cependant, sur le papier, cette restriction n'a pas beaucoup de sens puisque certains - si ce n'est tous - les clients de messagerie permettent de convertir la liste de distribution en une liste explicite de destinataires ; si la liste nommée infrasys contient les membres A, B et C, alors le client pourra faire un envoi aux trois destinataires A, B et C et non à la liste infrasys, ce qui contourne la limitation évoquée ci-dessus. Afin d'empêcher ce contournement, il est possible dans l'ActiveDirectory de paramétrer un attribut Exchange afin qu'il ne soit plus possible de dérouler cette liste.

Dans la console Active Directory Users and Computers que l'on peut appeler via dsa.msc, il suffit d'ouvrir le groupe AD qui porte la liste de distribution et de modifier l'attribut hideDLMembership (visible uniquement si les fonctionnalités avancées ont été activées dans la console).

La valeur se choisit dans une nouvelle fenêtre, la valeur Not Set étant celle par défaut, généralement équivalente à False : il est possible d'éclater la liste en destinataires explicites. En passant la valeur à True, les clients de messagerie ne pourront obtenir d'Exchange la liste des membres de la liste.

On conclut en validant simplement le choix. Ces quelques options et paramétrages permettent un meilleur usage et contrôle des listes de distribution dans Exchange 2010.

Exchange et Powershell : nettoyage des références caduques dans les ACL

Les ACL des boîtes aux lettres Exchange ne sont pas en synchronisation permanente avec l'ActiveDirectory, ce qui signifie que si l'on ajoute par exemple sur la boîte scranton@dundermifflin.inc l'utilisateur DUNDERMIFFLIN\jhalpert et que ce compte vient à disparaître de l'ActiveDirectory, alors cette boîte aura dans ses ACL une référence de type "S-1-5-***". Il se produit par exemple la même chose côté Windows si un compte de domaine est ajouté dans les profils locaux du système et que ce compte de domaine vient à disparaître.

Afin de faire un peu de nettoyage sur des boîtes aux lettres partagées, j'ai donc développé un script pour l'Exchange Management Shell (EMS) permettant de lister toutes les références à ces comptes qui n'existent plus. Cette liste est ensuite exportée au format CSV, ce qui permet ensuite de passer ce fichier si besoin dans un script supprimant ces références.

$Output = @()
$mailboxes = Get-Mailbox -ResultSize Unlimited
foreach($mailbox in $mailboxes){
	$acls = Get-MailboxPermission $mailbox | where-object { $_.User -like "S-1-5-21*" -and $_.IsInherited -eq $false -and $_.AccessRights -contains "FullAccess" }
	if($acls -ne $null){
		foreach ($acl in $acls) { 
			$obj = New-Object PSCustomObject
			$obj | Add-Member -MemberType NoteProperty -Name "Mailbox" -Value $mailbox.Name
			$obj | Add-Member -MemberType NoteProperty -Name "SID" -Value $acl.User
			$Output += $obj 
		}
	}
}
$Output | Export-CSV s1521-acl.csv -Encoding UTF8

Dans cet exemple, je ne touche qu'aux permissions qui ont été rajoutées manuellement (IsInherited -eq $false) et aux droits complets (FullAccess). Si je ne recommande pas de changer le premier critère, il est possible de changer FullAccess pour un autre valeur si besoin. Je vous renvoie vers la documentation Microsoft concernant la commande Get-MailboxPermission pour plus d'informations sur le sujet.

Une fois le fichier CSV obtenu, je peux me servir de ce snippet pour le parcourir et procéder à la suppression des entrées relevées :

$acls = Import-CSV s1521-acl.csv
foreach($acl in $acls){
	Write-Host "Processing"$acl.Mailbox"with SID"$acl.SID
	Remove-MailboxPermission -Identity $acl.Mailbox -User $acl.SID -AccessRights FullAccess -Confirm:$false
}

Ce premier script est disponible dans une version commentée à télécharger.

Exchange et Powershell : volumétrie des mails

Ce script à exécuter dans l'Exchange Management Shell qui prend pour paramètre un nombre de jours calcule grâce au tracking logs le nombre de mails qui ont été envoyés hors du domaine spécifié et reçus par un expéditeur hors du domaine, afin de pouvoir calculer une taille totale et une moyenne.

param([Parameter(Mandatory=$true)][int] $Days)
$today = (Get-Date)
$TrxS = Get-MessageTrackingLog -EventID "SEND" -Start $today.AddDays(-$Days) -End $today -ResultSize 5000
$TrxD = Get-MessageTrackingLog -EventID "DELIVER" -Start $today.AddDays(-$Days) -End $today -ResultSize 5000
$FltS = $TrxS | Where-Object { $_.Recipients -notmatch "@dundermifflin.inc"}
$FltD = $TrxD | Where-Object { $_.Sender -notmatch "@dundermifflin.inc" }
$FltS | foreach { $SendSize += $_.TotalBytes }
$FltD | foreach { $DelSize += $_.TotalBytes }
Write-Host "Total messages sent:"$FltS.Count
Write-Host "Total sent bytes:"$SendSize" ("([math]::Round($SendSize/1024/1024,1))"MB )"
Write-Host "Average sent message size (KB):"([math]::Round(($SendSize/$FltS.Count)/1024,1))`r`n
Write-Host "Total messages received:"$FltD.Count
Write-Host "Total received bytes:"$DelSize" ("([math]::Round($DelSize/1024/1024,1))"MB )"
Write-Host "Average received message size (KB):"([math]::Round(($DelSize/$FltD.Count)/1024,1))

Powershell : extraction des adresses du champ "To" d'une entête SMTP

J'ai développé en Powershell un script permettant d'extraire les adresses mail d'une en-tête SMTP. Mon but était de récupérer dans un fichier CSV une liste d'adresses pour effectuer sur ces adresses un traitement supplémentaire.

Dans Outlook, il suffit donc d'ouvrir l'entête SMTP du mail en question, de copier-coller le champ "To" dans un fichier texte et de le passer en paramètre lors de l'exécution du script pour obtenir la liste des adresses dans l'output console Powershell ainsi que dans le fichier CSV passé en paramètre. On peut donc l'appeler ainsi :

.\regex-to-smtp-header.ps1 -Header to.txt -CsvOutput addresses.csv

Voici le script, la version commentée est disponible après celui-ci.

param([Parameter(Mandatory=$true)][string]$Header, [Parameter(Mandatory=$true)][string]$CsvOutput)
$CsvExport = @()
$smtpheader = Get-Content -Path $Header -Raw -ErrorAction stop
while($smtpheader.IndexOf("<") -ne -1) {
    $ls = $smtpheader.IndexOf("<")
    $rs = $smtpheader.IndexOf(">")
    $adrlgt = $rs-$ls
    $adr = $smtpheader.SubString(($ls+1),($adrlgt-1))
    echo $adr
    $adrcsv=@{Address=$adr}
    $adrexp = New-Object PSObject -Property $adrcsv
    $CsvExport+=$adrexp
    $smtpheader = $smtpheader.Substring($rs+1,(($smtpheader.Length-$rs)-1))
}
$CsvExport | Export-CSV $CsvOutput -NoTypeInformation