Microsoft 365 : 15 commandes PowerShell pour vérifier la sécurité

Vérifiez rôles Entra, Conditional Access, consentements OAuth et paramètres Exchange avec 15 commandes en lecture seule, leurs permissions et leurs limites.

01

Quinze vérifications ciblées, avec des résultats à interpréter

Un compte trop privilégié, un consentement OAuth oublié ou un transfert externe peut rester invisible dans une revue rapide du portail. PowerShell aide à rendre ces configurations lisibles et à conserver une preuve reproductible.

Les 15 contrôles suivants lisent la configuration. Les commandes de préparation, de connexion et de fermeture sont séparées du décompte. Il ne s’agit pas d’un audit complet automatisé : absence de résultat, accès refusé et contrôle réellement réussi doivent rester trois états distincts.

Les exemples ciblent Microsoft Graph v1.0 et Exchange Online, avec des identifiants fictifs. Aucun contrôle ne retire de licence, ne révoque un consentement et ne change une stratégie.

02

Préparer les modules et une session autorisée

Utilisez une version prise en charge de PowerShell et des modules Microsoft.Graph.Authentication, Identity.Governance, Identity.SignIns, Applications et ExchangeOnlineManagement. Pour les versions EXO 3.5.0 à 3.9.2 sous PowerShell 7, Microsoft documente PowerShell 7.4.x; confirmez la matrice de votre version plutôt que d’installer aveuglément la dernière combinaison.

Installez ou mettez à jour les modules dans votre procédure de changement, pas au milieu d’une collecte. Consignez leurs versions. Les cmdlets Graph ci-dessous utilisent les modules stables, sans préfixe Beta. Adaptez aussi l’environnement de connexion si vous utilisez un cloud national.

Connectez-vous avec une identité nominative protégée par MFA. Un consentement de portée Graph peut créer une autorisation persistante : utilisez une application de collecte approuvée et faites autoriser uniquement les permissions nécessaires. ContextScope Process limite le contexte local de connexion; il ne révoque pas les consentements du locataire.

L’exemple de connexion ci-dessous suffit aux contrôles 4 et 5 seulement. Pour les autres blocs, demandez la portée indiquée dans le tableau. Une permission OAuth ne remplace pas le rôle Entra ou le RBAC Exchange du compte.

Préparation — hors des 15 contrôles
# Preparation, outside the 15 checks. Use approved installed versions.
$ErrorActionPreference = 'Stop'
Get-Module -ListAvailable Microsoft.Graph*,ExchangeOnlineManagement |
  Select-Object Name,Version

# Example for checks 4 and 5 only: request scopes by diagnostic block.
Connect-MgGraph -TenantId '00000000-0000-0000-0000-000000000000' -Scopes 'Policy.Read.All' -ContextScope Process
Get-MgContext | Select-Object TenantId,Account,Scopes
Connect-ExchangeOnline -UserPrincipalName admin@contoso.com
# All addresses and IDs in this guide are fictional.
03

Permissions : choisir le bloc utile

Les portées sont présentées par opération. Si une session approuvée possède déjà une portée plus large en lecture, ne rajoutez pas des permissions d’écriture. Le rôle Global Reader peut servir à plusieurs lectures Entra, mais n’est pas une solution universelle pour Exchange. Le contrôle 12 présente une exception importante.

Pour Exchange, faites identifier les entrées de rôle et les paramètres nécessaires par l’administrateur RBAC, puis déléguez la portée utile. Une commande absente ou une erreur 403 doit être notée « non évalué », jamais « conforme ».

ContrôlesPortée Graph minimale pour l’opérationAutre condition
1–2RoleManagement.Read.DirectoryRôle de lecture Entra pris en charge
3RoleEligibilitySchedule.Read.DirectoryRôle pris en charge; PIM et licences applicables
4–5Policy.Read.AllRôle pris en charge pour lire les stratégies
6Policy.Read.AuthenticationMethodPar exemple Global Reader selon l’API
7 et 9Application.Read.AllLecture des principaux de service
8Directory.Read.AllLecture du répertoire étendue, à justifier
10–15—RBAC Exchange, cmdlets et portée de destinataires
04

1. Nommer les rôles avant de compter les administrateurs

Permission de collecte : RoleManagement.Read.Directory.

Conservez cette table pour résoudre RoleDefinitionId à l’étape 2. Un rôle défini n’est pas nécessairement attribué; examinez aussi les rôles personnalisés.

Lecture seule
$roles = @(Get-MgRoleManagementDirectoryRoleDefinition -All -ErrorAction Stop)
$roles | Select-Object Id,DisplayName,IsBuiltIn,IsEnabled
05

2. Lister les attributions de rôles actives

Permission de collecte : RoleManagement.Read.Directory.

Reliez les identifiants aux rôles du contrôle 1 et aux principaux dans Entra. Un principal peut être un utilisateur, un groupe ou une application. Développez les groupes attribuables aux rôles avant de compter les personnes. Cette liste ne couvre pas les éligibilités non activées.

Lecture seule
Get-MgRoleManagementDirectoryRoleAssignment -All -ErrorAction Stop |
  Select-Object Id,PrincipalId,RoleDefinitionId,DirectoryScopeId,AppScopeId
06

3. Relever les éligibilités PIM séparément

Permission de collecte : RoleEligibilitySchedule.Read.Directory.

Une éligibilité n’est pas une activation. Comparez durée, portée et besoin du propriétaire. PIM exige les licences Entra ID P2 ou ID Governance appropriées. Un accès refusé ne signifie pas qu’il n’y a aucune éligibilité.

Lecture seule
Get-MgRoleManagementDirectoryRoleEligibilityScheduleInstance -All -ErrorAction Stop |
  Select-Object Id,PrincipalId,RoleDefinitionId,DirectoryScopeId,StartDateTime,EndDateTime
07

4. Lire les stratégies Conditional Access

Permission de collecte : Policy.Read.All.

Inspectez exclusions, ressources, plateformes et contrôles. Report-only observe sans appliquer les décisions de cette stratégie. Un nom « MFA partout » ne prouve aucune couverture. Conditional Access exige Entra ID P1; les conditions de risque exigent P2. Validez ensuite avec What If et journaux.

Lecture seule
Get-MgIdentityConditionalAccessPolicy -All -ErrorAction Stop |
  Select-Object Id,DisplayName,State,Conditions,GrantControls,SessionControls |
  ConvertTo-Json -Depth 20
08

5. Vérifier les paramètres de sécurité par défaut

Permission de collecte : Policy.Read.All.

IsEnabled décrit ce mécanisme, pas la sécurité globale. False peut être cohérent avec une architecture Conditional Access. True ne prouve pas qu’une connexion précise a été protégée. Les paramètres de sécurité par défaut sont disponibles avec Entra ID Free.

Lecture seule
Get-MgPolicyIdentitySecurityDefaultEnforcementPolicy -ErrorAction Stop |
  Select-Object Id,DisplayName,IsEnabled
09

6. Inspecter la stratégie des méthodes d’authentification

Permission de collecte : Policy.Read.AuthenticationMethod.

Examinez méthodes activées, groupes inclus et exclusions. Une méthode autorisée ne signifie pas que les utilisateurs l’ont enregistrée, ni qu’une force d’authentification l’impose. Complétez avec les rapports d’inscription et les stratégies applicables.

Lecture seule
Get-MgPolicyAuthenticationMethodPolicy -ExpandProperty AuthenticationMethodConfigurations -ErrorAction Stop |
  ConvertTo-Json -Depth 20
10

7. Inventorier les applications d’entreprise

Permission de collecte : Application.Read.All.

Ce sont des principaux de service du locataire, pas uniquement les inscriptions d’applications dont vous êtes propriétaire. Conservez $apps pour le contrôle 9. Un nom familier ou une application désactivée ne remplace pas la vérification des permissions et du propriétaire.

Lecture seule
$apps = @(Get-MgServicePrincipal -All -Property Id,AppId,DisplayName,AccountEnabled,AppRoles -ErrorAction Stop)
$apps | Select-Object Id,AppId,DisplayName,AccountEnabled
11

8. Lire les consentements délégués OAuth

Permission de collecte : Directory.Read.All.

Scope contient des permissions déléguées. ClientId et ResourceId sont ici des identifiants d’objets servicePrincipal, pas l’AppId public. AllPrincipals désigne un consentement pour tous; Principal désigne un utilisateur. Vérifiez justification et besoin avant toute révocation.

Lecture seule
Get-MgOauth2PermissionGrant -All -ErrorAction Stop |
  Select-Object Id,ClientId,ResourceId,ConsentType,PrincipalId,Scope
12

9. Lire les permissions applicatives d’une application pilote

Permission de collecte : Application.Read.All.

Ces attributions sont distinctes des consentements délégués. Elles peuvent permettre un accès sans utilisateur connecté. Si Permission est vide, conservez l’identifiant et résolvez-le dans l’API cible; ne concluez pas à une absence de droit. Le script couvre une seule application choisie.

Lecture seule
# Use check 7 to select the exact service principal OBJECT ID.
$clientObjectId = '11111111-1111-1111-1111-111111111111'
Get-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $clientObjectId -All -ErrorAction Stop |
  ForEach-Object {
    $grant = $_
    $resource = $apps | Where-Object Id -eq $grant.ResourceId
    $role = $resource.AppRoles | Where-Object Id -eq $grant.AppRoleId
    [pscustomobject]@{
      ClientObjectId=$clientObjectId; ResourceId=$grant.ResourceId
      Resource=$resource.DisplayName; AppRoleId=$grant.AppRoleId
      Permission=$role.Value
    }
  }
13

10. Lire l’état d’audit de l’organisation Exchange

Permission de collecte : Exchange RBAC.

AuditDisabled doit se lire dans le bon sens : True désactive l’audit de boîte au niveau organisationnel. False ne garantit ni les événements attendus, ni leur rétention, ni l’absence d’exclusions. Confirmez la recherche d’un événement test et les licences Purview pertinentes.

Lecture seule
Get-OrganizationConfig -ErrorAction Stop |
  Select-Object Name,AuditDisabled
14

11. Rechercher les transferts configurés sur les boîtes

Permission de collecte : Exchange RBAC.

Une destination d’annuaire peut être un contact à adresse externe : résolvez-la avant de classer le transfert. Cette collecte ne voit pas les règles de boîte ou de transport. Elle identifie une configuration, pas une exfiltration prouvée.

Lecture seule
Get-EXOMailbox -ResultSize Unlimited -Properties ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForward -ErrorAction Stop |
  Where-Object { $_.ForwardingAddress -or $_.ForwardingSmtpAddress } |
  Select-Object DisplayName,PrimarySmtpAddress,ForwardingAddress,ForwardingSmtpAddress,DeliverToMailboxAndForward
15

12. Examiner les règles d’une boîte pilote, y compris cachées

Permission de collecte : Exchange RBAC spécifique.

Microsoft indique que cette cmdlet ne fonctionne pas avec View-Only Organization Management ni avec le rôle Entra Global Reader. Faites déléguer les entrées Get-InboxRule et la portée de destinataires nécessaires; n’accordez pas un rôle global d’écriture pour contourner cette limite. Préservez les détails complets des règles suspectes avant remédiation.

Lecture seule
Get-InboxRule -Mailbox 'alex@contoso.com' -IncludeHidden -ResultSize Unlimited -ErrorAction Stop |
  Select-Object Identity,Name,Enabled,Priority,ForwardTo,RedirectTo,ForwardAsAttachmentTo,DeleteMessage,StopProcessingRules
16

13. Lire les politiques de transfert sortant

Permission de collecte : Exchange RBAC.

La présence d’une politique restrictive ne prouve pas qu’elle cible tous les destinataires. Vérifiez séparément les règles d’affectation, priorités et exceptions. Comparez AutoForwardingMode à la documentation du service; évitez de supposer que Automatic signifie autorisé.

Lecture seule
Get-HostedOutboundSpamFilterPolicy -ErrorAction Stop |
  Select-Object Name,IsDefault,AutoForwardingMode
17

14. Lire le paramètre SMTP AUTH du locataire

Permission de collecte : Exchange RBAC.

True décrit la désactivation au niveau organisationnel. Les paramètres de boîte, les stratégies d’authentification et les contrôles Entra peuvent modifier le résultat effectif. SMTP AUTH et Basic Authentication ne sont pas synonymes : ce booléen ne prouve pas l’usage d’OAuth ni l’absence de connexions héritées.

Lecture seule
Get-TransportConfig -ErrorAction Stop |
  Select-Object SmtpClientAuthenticationDisabled
18

15. Repérer les règles de transport à examiner

Permission de collecte : Exchange RBAC.

Examinez redirections, copies cachées, exceptions et réglages antispam inhabituels. Une règle de test n’agit pas comme une règle appliquée. L’extrait n’expose pas toutes les actions : ouvrez le détail complet de toute règle retenue et validez avec son propriétaire.

Lecture seule
Get-TransportRule -ResultSize Unlimited -ErrorAction Stop |
  Sort-Object Priority |
  Select-Object Identity,Name,State,Mode,Priority,Description,RedirectMessageTo,BlindCopyTo,SetSCL
19

Conserver des preuves sans transformer une revue en balayage aveugle

Commencez par une application et une boîte pilote. Les contrôles Graph utilisent -All pour parcourir les pages; les commandes Exchange utilisent ResultSize Unlimited lorsque pertinent. Cela ne supprime ni restrictions de portée ni limitation de débit. Évitez la parallélisation massive; conservez les erreurs et les nouvelles tentatives dans le dossier de collecte.

Notez locataire, compte collecteur, date et heure UTC, version des modules, commande et périmètre. Les tableaux Format-Table ne doivent pas servir de source d’export; conservez les objets avant formatage. Utilisez JSON à profondeur adaptée ou CliXML pour les valeurs imbriquées; un CSV peut aplatir ou perdre les groupes, conditions et actions.

Les résultats contiennent adresses, identifiants et détails sensibles de sécurité. Définissez emplacement, accès et rétention. Un instantané décrit un état à un moment donné; il ne montre pas à lui seul l’historique des changements ou l’utilisation réelle des permissions.

20

Passer des constats aux changements, avec validation et retour arrière

Classez les résultats selon exposition et impact : rôle administratif injustifié, accès applicatif très large ou transfert externe inconnu méritent une validation rapide. Associez chaque constat à un propriétaire et à une preuve; ne révoquez pas une application simplement parce que son nom est inconnu.

Les changements restent un travail distinct : export de l’état initial, confirmation du besoin métier, périmètre pilote, tests, fenêtre et procédure de retour arrière. Pour Conditional Access, passez par Report-only et les comptes d’urgence; pour Exchange, validez les flux légitimes. Une suppression de consentement ou d’attribution peut nécessiter un nouvel accord pour être restaurée.

Après remédiation, relancez le contrôle ciblé et un test fonctionnel. Déconnectez les sessions de collecte. Disconnect-MgGraph ferme la session locale, sans supprimer les autorisations accordées à l’application. Faites réviser les consentements de collecte devenus inutiles.

Ce point de départ peut préparer un audit de sécurité Microsoft 365 et Entra ID. L’analyse professionnelle relie les résultats aux journaux, aux dépendances, aux licences et aux risques réels; elle ne se résume pas à quinze sorties PowerShell.

Fermeture des sessions — hors décompte
Disconnect-MgGraph
Disconnect-ExchangeOnline -Confirm:$false