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

Exchange et Powershell : uniformisation des adresses mail

Ce script Powershell récupère la liste des mailbox présentes pour les utilisateurs membres de l’OU spécifiée et ajoute comme adresse mail principale une adresse au format prenom.nom@domaine.tld.

Ce script permet donc d’uniformiser les adresses mail en gérant les divers caractères spéciaux et accents, tout en conservant les anciennes adresses qui peuvent servir comme alias, évitant d’avoir à communiquer par rapport à sa nouvelle adresse.

function process {
	Param([string] $name)
	$specials = @("- '","âä","éèëê","ïîì","ôö","üûù","ÿ")
	for($i=0; $i -lt $specials.Length; $i++) {
		for($j=0; $j -lt $specials[$i].Length; $j++) {
			switch($i) {
				"0" { $l = "" }
				"1" { $l = "a" }
				"2" { $l = "e" }
				"3" { $l = "i" }
				"4" { $l = "o" }
				"5" { $l = "u" }
				"6" { $l = "y" }
			}
			$name = $name.Replace(($specials[$i].SubString($j,1)),$l)
		}
	}
	return $name
}
 
$mailboxes = Get-Mailbox | Where-Object { $_.OrganizationalUnit -like "dundermifflin.inc/USERS/*"}
foreach ($mailbox in $mailboxes) {
	$adUser = Get-AdUser $mailbox.Name
	$newsmtp = ((process($adUser.GivenName))+"."+(process($adUser.Surname))).ToLower()+"@dundermifflin.inc"
	Set-Mailbox $mailbox -PrimarySmtpAddress $newsmtp
}

Comme toujours, vous pouvez télécharger le script dans une version commentée grâce au lien suivant.