Le blog technique

Toutes les astuces #tech des collaborateurs de PI Services.

#openblogPI

Retrouvez les articles à la une

[PowerShell] Envoi d’e-mails : Send-MailMessage vs Send-MgUserMail

L’envoi d’e-mails est une fonctionnalité centrale dans de nombreux scripts PowerShell : rapports d’audit, alertes, notifications ou comptes rendus automatisés. Historiquement, la cmdlet Send-MailMessage a longtemps été la solution privilégiée. Avec l’évolution de Microsoft 365 et l’arrivée de Microsoft Graph, de nouvelles approches ont émergé, notamment via Send-MgUserMail.

Ces deux méthodes répondent au même besoin fonctionnel, mais reposent sur des modèles très différents, avec des impacts importants en matière de sécurité, d’authentification et de pérennité.

Send-MailMessage repose sur le protocole SMTP. Il s’agit d’une cmdlet simple à mettre en œuvre, largement utilisée dans les scripts historiques. Elle nécessite toutefois l’accès à un serveur SMTP, souvent avec une authentification basique ou un compte technique.

Avec le durcissement de la sécurité Microsoft 365 et la fin progressive de l’authentification basique, cette méthode devient de plus en plus contraignante. Elle est aujourd’hui marquée comme obsolète par Microsoft et n’est plus recommandée pour de nouveaux développements.

À l’inverse, Send-MgUserMail s’appuie sur Microsoft Graph et fonctionne via des API modernes. L’envoi du message est réalisé au nom d’un utilisateur ou d’une application, en respectant les mécanismes d’authentification modernes (OAuth 2.0).

Cette approche s’intègre naturellement aux environnements Microsoft 365 sécurisés, mais demande une configuration initiale plus structurée, notamment au niveau des permissions Graph.

Envoi d’e-mail via Send-MailMessage (SMTP)

$SmtpParams = @{
    From       = $SmtpFrom
    To         = $SmtpTo
    Cc         = $SmtpCc
    Subject    = $Subject
    Body       = $Body
    BodyAsHtml = $True
    SmtpServer = $SmtpServer
}

Send-MailMessage @SmtpParams -Attachments $FilePath_1, $FilePath_2

Note: le paramètre "Attachments » est là pour rajouter des pièces jointes au mail, ici les arguments représente le chemin du fichier.

Envoi d’e-mail via Send-MgUserMail (Microsoft Graph)

Prérequis:

  • Module Microsoft Graph
  • Utilisateur ou une application autorisée à envoyer des e-mails (Mail.Send)

Deux modèles d’authentification possibles:

Connexion en mode déléguée :

Connect-MgGraph -Scopes "Mail.Send"

Connexion en mode applicative (avec un certificat ou un secret) :

Connect-MgGraph -TenantId "<TenantId>" -ClientId "<AppId>" -CertificateThumbprint "<Thumbprint>"

Une fois la connexion à Graph faite, ci-dessous un template pour envoyer un mail avec un .csv en pièce jointe:

$SmtpFrom = "sender@contoso.com"
$To_Recipients = "mail1@contoso.com", "mail2@contoso.com"
$Cc_Recipients = "mail3@contoso.com", "mail4@contoso.com"
$EmailSubject = "Mail Subject"

# Lit un fichier, le convertit en Base64 et récupère son nom pour une pièce jointe.
$AttachmentContentBytes_1 = [System.IO.File]::ReadAllBytes($FilePath_1)
$AttachmentBase64_1 = [System.Convert]::ToBase64String($AttachmentContentBytes_1)
$AttachmentName_1 = [System.IO.Path]::GetFileName($FilePath_1)

# Formatage nécessaire pour l'envoie à plusieurs destinataire
$To_Recipients_List = @()
foreach ($To_Recipient in $To_Recipients) {
    $To_Recipients_List += @{
        EmailAddress = @{
            Address = $To_Recipient
        }
    }
}

$Cc_Recipients_List = @()
foreach ($Cc_Recipient in $Cc_Recipients) {
    $Cc_Recipients_List += @{
        EmailAddress = @{
            Address = $Cc_Recipient
        }
    }
}

$EmailProperties = @{
    ToRecipients = $To_Recipients_List
    CcRecipients = $Cc_Recipients_List
    Subject      = $EmailSubject
    Body         = @{
        ContentType = "HTML"
        Content     = $Body
    }
    Attachments  = @(
        @{
            "@odata.type" = "#microsoft.graph.fileAttachment"
            Name          = $AttachmentName_1
            ContentBytes  = $AttachmentBase64_1
            ContentType   = "text/csv"
        }
    )
}

Send-MgUserMail -UserId $SmtpFrom -Message $EmailProperties

Note : le paramètre UserId représente la boîte aux lettres émettrice, il faut s’assurer qu’elle existe réellement sinon l’envoie ne fonctionnera pas.

[Microsoft Defender for Identity] – Comprendre et corriger les alertes liées aux capteurs MDI

Microsoft Defender for Identity (MDI) est une solution de sécurité conçue pour détecter les activités suspectes et les attaques avancées ciblant Active Directory. Elle s’appuie sur des sensors installés sur les contrôleurs de domaine, chargés d’analyser le trafic réseau, les authentifications et les comportements anormaux au sein de l’annuaire.

Pour que la détection soit fiable, ces sensors doivent fonctionner dans des conditions techniques précises. Lors de la mise en œuvre ou de l’exploitation de MDI, certaines alertes peuvent apparaître, non pas à cause d’une attaque, mais à cause d’une configuration non optimale de l’environnement. C’est notamment le cas des alertes liées à la gestion de l’énergie et à la configuration réseau sur des environnements virtualisés.

Dans mon cas, deux alertes revenaient régulièrement dans le portail Defender for Identity :

  • Sensor with non-optimal power settings
  • Network configuration mismatch for sensors running on VMware

La première alerte indique que le contrôleur de domaine utilise un mode de gestion de l’alimentation incompatible avec les exigences de MDI. Par défaut, Windows Server peut être configuré en mode Balanced, ce qui autorise le système à réduire la fréquence CPU. Or, le sensor MDI nécessite des performances constantes pour analyser le trafic en temps réel.

La correction consiste à forcer le plan d’alimentation en High Performance sur les contrôleurs de domaine concernés.

Correction en PowerShell :

powercfg /L
powercfg /S SCHEME_MIN

Après application, un redémarrage du serveur est recommandé afin de garantir la prise en compte complète du changement. Une fois le plan appliqué, l’alerte disparaît généralement après quelques minutes.

La seconde alerte concerne les environnements virtualisés sous VMware. Elle apparaît lorsque la configuration réseau du contrôleur de domaine ne permet pas au sensor MDI d’observer correctement le trafic, notamment à cause d’un mode de carte réseau inadapté ou d’une incohérence entre les interfaces détectées.

MDI attend une visibilité réseau complète. Sur VMware, cela implique généralement :

  • une seule carte réseau active pour le DC
  • une carte configurée en VMXNET3
  • pas de NIC de sauvegarde ou de supervision mal configurée
  • pas de teaming non supporté

Pour identifier rapidement les interfaces réseau et leurs paramètres :

Get-NetAdapter | Select Name, Status, LinkSpeed, DriverDescription

Sur VMware, certaines optimisations réseau comme Large Send Offload (LSO) modifient la manière dont les paquets sont traités :

  • les paquets sont regroupés côté OS
  • la segmentation est déléguée à la carte réseau virtuelle
  • le sensor MDI ne voit plus le trafic tel qu’il est réellement émis

Microsoft recommande explicitement de désactiver LSO sur les DC protégés par MDI.

Correction en PowerShell:

Get-NetAdapterAdvancedProperty -Name "*" | Where-Object DisplayName -Match "Large Send Offload" | Set-NetAdapterAdvancedProperty -DisplayValue "Disabled"

Un redémarrage du serveur est fortement recommandé après la modification.

Ces alertes rappellent que Microsoft Defender for Identity dépend fortement de la qualité de la configuration système et réseau. Corriger ces points permet non seulement de supprimer les alertes, mais surtout de garantir une détection fiable et complète des activités suspectes au sein d’Active Directory.

[Active Directory] OU protégée contre la suppression : comprendre les impacts réels

Lors de la mise en place de délégations Active Directory, le ciblage et la gestion des droits sur les unités d’organisation semblent, en théorie, relativement simples. Les permissions sont correctement attribuées, les groupes sont en place, et pourtant certaines actions échouent systématiquement avec des erreurs de type Access Denied. Dans ce contexte, le diagnostic peut rapidement devenir frustrant, car les droits semblent cohérents et conformes aux attentes.

Ce type de situation est fréquemment lié à l’option “Protect object from accidental deletion”, souvent activée par défaut sur les OU sensibles. Cette protection est une bonne pratique, mais son impact réel est souvent sous-estimé, notamment lors de la mise en œuvre de délégations.

Concrètement, cette option ne se limite pas à empêcher une suppression accidentelle via l’interface graphique. Lorsqu’elle est activée, Active Directory ajoute automatiquement des entrées explicites de type Deny dans les ACL de l’OU. Ces entrées bloquent des actions critiques comme la suppression de l’OU, la suppression d’objets enfants ou certains déplacements dans l’arborescence.

Le point clé à comprendre est que, dans Active Directory, un Deny explicite prévaut toujours sur un Allow, quel que soit le niveau de privilège accordé par ailleurs. Ainsi, même une délégation correctement configurée peut être partiellement inefficace tant que ces ACE de protection sont présentes. Le résultat est souvent une erreur peu explicite, sans lien apparent avec la protection active.

C’est précisément ce comportement qui explique pourquoi certaines délégations semblent « ne pas fonctionner”, alors que les permissions sont correctes sur le papier. Sans analyse des paramètres de sécurité avancés, il est facile de conclure à une erreur de configuration, alors que le blocage est en réalité intentionnel.

La résolution passe par une analyse systématique des ACL de l’OU concernée. Dans certains cas, il est nécessaire de désactiver temporairement la protection afin d’effectuer l’opération prévue, puis de la réactiver une fois la modification terminée. Cette approche permet de conserver le niveau de sécurité attendu tout en évitant les blocages inutiles.

Avec cette compréhension, les délégations deviennent plus prévisibles, les erreurs Deny plus faciles à expliquer, et l’administration Active Directory globalement plus fiable. La protection contre la suppression reste un mécanisme essentiel, à condition d’en connaître les impacts réels et de l’intégrer consciemment dans les scénarios d’administration.