# Coder soi-même son audit Microsoft 365 avec l'IA : quand c'est la bonne réponse

> Avec Microsoft Graph et un assistant de code IA, un script d'audit M365 se code en un week-end. Ce qui coûte vient après : API, détections, preuve.

Source: https://olyteck.com/blog/fr/coder-soi-meme-audit-microsoft-365
Published: 2026-09-25
Author: Oleg Garasym, Olyteck (France, EU-hosted)
Product: Olyteck Cyber
Topics: microsoft 365, microsoft graph, powershell, audit, liens anonymes, applications oauth, entra id, gouvernance
License: free to quote with attribution to Olyteck and a link to the source URL.

---

Dans les grandes entreprises françaises, le sujet a changé de nature. Certaines directions
informatiques envisagent de remplacer une partie de leurs abonnements SaaS par des applications
développées en interne avec l'IA. D'autres standardisent déjà une pile de développement assisté par
IA validée par la sécurité, avec SSO et base de données commune. « On va le faire nous-mêmes » n'est
plus un projet de week-end d'un administrateur passionné : cela devient une politique d'entreprise.

L'audit Microsoft 365 est un candidat évident. Les API sont documentées, les exemples abondent, et un
assistant de code IA écrit du PowerShell correct en quelques minutes. Cet article prend l'idée au
sérieux : un script fonctionnel, ce qu'il coûte vraiment de le faire vivre, et les cas où le coder
soi-même est tout simplement le bon choix.

## Le scan n'est pas la partie difficile

Disons-le franchement : avec Microsoft Graph et un assistant de code IA, un administrateur compétent
obtient un premier script d'audit qui tourne en un week-end. Voici un exemple minimal, en lecture
seule, qui liste les liens [« Tout le monde disposant du lien »](/blog/fr/trouver-liens-partage-anonymes-microsoft-365) (portée `anonymous`) sur les éléments
d'un seul OneDrive.

```powershell
# Lecture seule : liste les liens "anonymous" sur les éléments d'UN OneDrive.
# En délégué, Graph ne renvoie tous les liens que sur les éléments dont vous êtes
# propriétaire. Pour le OneDrive d'un autre utilisateur, connectez-vous en
# app-only (certificat) avec la permission d'application Files.Read.All.
Connect-MgGraph -Scopes "Files.Read.All", "Sites.Read.All" -NoWelcome

$upn   = "prenom.nom@votredomaine.fr"            # le OneDrive à contrôler
$drive = Get-MgUserDefaultDrive -UserId $upn
$root  = Get-MgDriveRoot -DriveId $drive.Id

function Get-AnonymousLinks($DriveId, $ItemId, $Path) {
    # -All suit la pagination (@odata.nextLink, 200 éléments par page par défaut)
    foreach ($item in Get-MgDriveItemChild -DriveId $DriveId -DriveItemId $ItemId -All) {
        $itemPath = "$Path/$($item.Name)"
        # Les permissions ne s'étendent pas depuis la liste : un appel par élément
        Get-MgDriveItemPermission -DriveId $DriveId -DriveItemId $item.Id -All |
            Where-Object { $_.Link.Scope -eq "anonymous" -and -not $_.InheritedFrom.Id } |
            ForEach-Object {
                [pscustomobject]@{
                    Path    = $itemPath
                    Type    = $_.Link.Type              # view ou edit
                    Expires = $_.ExpirationDateTime
                }
            }
        # Récursion sans limite de profondeur : chaque dossier relance la fonction
        if ($item.Folder.ChildCount -gt 0) {
            Get-AnonymousLinks -DriveId $DriveId -ItemId $item.Id -Path $itemPath
        }
    }
}

Get-AnonymousLinks -DriveId $drive.Id -ItemId $root.Id -Path "" | Format-Table
```

Il fonctionne, et ses limites sont honnêtes à énoncer :

- Il couvre un seul drive : pour tout le tenant, il faut énumérer chaque OneDrive, chaque site et chaque bibliothèque.
- La récursion descend sans limite : une arborescence profonde multiplie les appels et la durée.
- Chaque élément coûte un appel de permissions : sur un gros tenant, comptez en heures, pas en minutes.
- Graph renvoie des erreurs 429 quand vous allez trop vite ; le SDK respecte l'en-tête Retry-After, mais le temps d'exécution s'allonge d'autant.
- En délégué, un appelant qui n'est pas propriétaire de l'élément ne voit que les permissions qui le concernent ; l'inventaire complet passe par une application app-only, donc une inscription d'application, un certificat et un consentement administrateur.
- Le filtre sur `InheritedFrom` évite les doublons : un lien posé sur un dossier est signalé une fois, au niveau du dossier.

Rien de tout cela n'est insurmontable. C'est justement le point : la boucle se code. Le reste coûte.

## L'API bouge, et votre script avec

Microsoft Graph distingue deux versions. La v1.0 est destinée à la production ; la version beta peut
changer ou disparaître à tout moment, et son usage en production n'est pas pris en charge. Or
certaines données utiles à un audit n'existent d'abord qu'en beta, et un assistant de code IA
propose volontiers l'une comme l'autre. Côté v1.0, Microsoft annonce une dépréciation au moins 24 mois
avant le retrait d'une API : c'est confortable, à condition que quelqu'un lise le journal des
modifications.

Les deux dernières années ont montré ce que cela signifie concrètement :

- Les modules PowerShell MSOnline et AzureAD, dépréciés depuis le 30 mars 2024, ont été retirés en 2025 : MSOnline entre début avril et fin mai, AzureAD après le 1er juillet.
- Azure ACS, l'ancien mécanisme d'authentification d'applications pour SharePoint Online, a cessé de fonctionner pour tous les tenants le 2 avril 2026, sans option de prolongation.
- Les compléments SharePoint (SharePoint Add-Ins) se sont arrêtés à la même date, le 2 avril 2026.

Chacun de ces retraits a cassé des scripts qui fonctionnaient parfaitement la veille. Un outil maison
n'est pas un livrable, c'est un abonnement à la documentation Microsoft que vous payez en heures.

## La bibliothèque de détections est le produit

Le script ci-dessus répond à une question. Un audit en pose des dizaines : sites ouverts à « Tout le
monde sauf les utilisateurs externes », invités, [OneDrive d'anciens salariés](/blog/fr/depart-salarie-onedrive-partages-acces), équipes sans
propriétaire, comptes administrateurs inactifs, consentements OAuth, règles de transfert de
messagerie. Et la liste s'allonge à chaque nouvelle fonctionnalité : nouveaux types de partage,
Copilot qui rend visible tout ce qu'un utilisateur peut déjà lire, [agents qui agissent](/blog/fr/agents-ia-microsoft-365-surface-attaque) avec des
permissions déléguées, applications qui demandent des scopes plus larges qu'hier.

Savoir quoi chercher, et le tenir à jour, c'est le vrai travail. La boucle qui parcourt le tenant est
la partie commune à tous les contrôles ; la connaissance de ce qui est risqué, et de ce qui a changé
ce trimestre, est ce qui fait la valeur d'un audit. Un assistant de code IA écrit très bien la
boucle. Il ne vous dira pas quelle détection manque.

## La trace, et la question de l'auditeur

Un script imprime un état. L'auditeur, lui, demande une histoire datée : ce qui a été trouvé, quand,
qui l'a corrigé, à quelle date, et ce qui prouve que la correction a tenu. Un export CSV du jour ne
répond à aucune de ces questions. Pour y répondre, il faut stocker chaque exécution, comparer les
résultats d'une semaine à l'autre, journaliser les corrections avec leur auteur, et conserver le tout
de façon à ce que personne ne puisse le réécrire après coup. C'est un second projet, plus long que le
premier.

Vient ensuite la question que l'auditeur pose rarement en ces termes, mais qu'il pose toujours : qui
a écrit le contrôle, qui peut le modifier, et la personne contrôlée est-elle celle qui a écrit le
contrôle ? Quand l'administrateur du tenant code le script qui audite ses propres choix de
configuration, peut le modifier et en présente seul les résultats, la séparation des tâches n'existe
pas. Ce n'est pas un procès d'intention : c'est la question de base de tout dispositif de contrôle.

## Qui le maintient quand son auteur part ?

C'est la question qui clôt la discussion. Le script vit dans un dépôt, sur un poste ou dans une tâche
planifiée. Il dépend d'un certificat qui expire, d'une inscription d'application que seul son auteur
connaît, et d'hypothèses qu'il n'a jamais écrites. Le jour où il quitte l'entreprise, le contrôle
continue de tourner, ou s'arrête sans que personne ne s'en aperçoive.

C'est exactement ce qu'un audit trouve dans le tenant lui-même : des espaces sans propriétaire. Des
équipes dont le dernier propriétaire est parti, des OneDrive d'anciens salariés, des liens créés par
quelqu'un qui n'est plus là. Un outil d'audit sans propriétaire est le même problème, un cran plus
haut.

## L'effet de second ordre : vos applications internes dans Entra ID

Le développement assisté par IA a une conséquence moins visible. Chaque application interne qui
propose « Se connecter avec Microsoft » est inscrite dans Entra ID : un objet application, et un
principal de service visible dans les applications d'entreprise. Par défaut, un utilisateur peut
inscrire une application, et il en devient automatiquement propriétaire. Les permissions déléguées
qu'elle demande sur Microsoft Graph sont souvent consenties par la personne qui l'a construite, puis
par ses collègues à leur première connexion.

Ces applications apparaissent dans la liste des consentements OAuth du tenant, à côté des
applications tierces. Trois questions pour chacune :

- Qui en est propriétaire aujourd'hui, et cette personne est-elle toujours dans l'entreprise ?
- Quels scopes ont été consentis, et sont-ils plus larges que ce que l'application utilise ?
- L'application sert-elle encore, ou son consentement survit-il à un prototype abandonné ?

Si votre entreprise encourage le développement assisté par IA, cette liste va grandir. Autant la
regarder dès maintenant, et vérifier le réglage « Les utilisateurs peuvent inscrire des
applications » dans Entra ID.

## Quand coder soi-même est la bonne réponse

Il y a des cas où c'est clairement le bon choix, et il faut le dire :

- Une équipe technique qui a réellement du temps à y consacrer, et quelqu'un pour le maintenir.
- Un seul tenant, stable, sans filiale ni tenant à consolider.
- Un besoin ponctuel : un inventaire avant une migration, une vérification après un incident.
- Aucun auditeur à satisfaire, ni ISO 27001, ni maison mère, ni client qui demande des preuves.
- L'apprentissage : écrire ce script est la meilleure façon de comprendre le modèle de partage de Microsoft 365.
- Un contrôle très spécifique à votre organisation, qu'aucun outil du marché ne couvrira jamais.

La règle générale tient en deux phrases :

> Construisez ce qui vous différencie : vos processus, vos flux métier. Achetez les contrôles qui
> doivent être indépendants, maintenus et prouvables.

## Comment Olyteck aborde le sujet

**Olyteck Cyber** parcourt le tenant avec une application dont les 19 permissions Microsoft Graph sont
toutes en lecture seule, sans agent ni export de fichiers. Il couvre sept modules, dont les liens
anonymes SharePoint et OneDrive, l'identité Entra ID et les applications OAuth, avec les consentements
accordés, les scopes à risque et les consentements inactifs. Nous comptons les constats, jamais vos
fichiers : seuls des compteurs, des indicateurs et des sévérités sont stockés. Chaque réponse indique
sa couverture, par exemple le nombre de sites analysés sur le total. Les offres payantes ajoutent des
scans quotidiens et hebdomadaires avec un rapport des seuls changements, et chaque correction est
journalisée avec la date, l'administrateur, l'objet et le résultat, exportable pour l'auditeur. Le
premier rapport arrive en quelques minutes ; sur un gros tenant, l'analyse complète se poursuit en
tâche de fond.

## FAQ

### Un assistant de code IA peut-il écrire un script d'audit Microsoft 365 fiable ?

Pour la boucle de scan, oui, à condition de relire le code et de vérifier chaque cmdlet dans la
documentation Microsoft Graph PowerShell. Les erreurs typiques sont un appel à l'API beta présenté
comme stable, une pagination oubliée ou une permission plus large que nécessaire. La fiabilité dans
la durée dépend de la maintenance, pas de la première version.

### Quelles permissions faut-il pour auditer les liens de partage en lecture seule ?

La lecture des permissions d'un élément demande au minimum Files.Read en délégué et Files.Read.All
en application ; Sites.Read.All convient aussi. En délégué, Graph ne renvoie l'ensemble des liens
que pour les éléments dont vous êtes propriétaire. Pour un inventaire du tenant, il faut donc une
application app-only avec consentement administrateur, et aucune permission d'écriture.

### Comment repérer les applications internes inscrites dans Entra ID ?

Dans le centre d'administration Entra, la page Inscriptions d'applications liste les applications
créées dans votre tenant avec leurs propriétaires, et la page Applications d'entreprise montre les
principaux de service et leurs permissions consenties. Côté Graph, la ressource oauth2PermissionGrant
recense les permissions déléguées accordées. Cherchez les applications sans propriétaire actif ou
sans connexion récente.

### Un script maison peut-il suffire pour un audit ISO 27001 ou de la maison mère ?

Il peut suffire si vous conservez des résultats datés, un journal des corrections avec leur auteur,
et une réponse claire sur qui a écrit et qui peut modifier le contrôle. C'est faisable, mais c'est un
projet à part entière. Demandez à votre auditeur, avant de coder, quelle preuve il attend.

## Sources

- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.authentication/connect-mggraph?view=graph-powershell-1.0
- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.files/get-mguserdefaultdrive?view=graph-powershell-1.0
- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.files/get-mgdriveroot?view=graph-powershell-1.0
- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.files/get-mgdriveitemchild?view=graph-powershell-1.0
- https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.files/get-mgdriveitempermission?view=graph-powershell-1.0
- https://learn.microsoft.com/en-us/graph/api/driveitem-list-permissions?view=graph-rest-1.0
- https://learn.microsoft.com/en-us/graph/api/driveitem-list-children?view=graph-rest-1.0
- https://learn.microsoft.com/en-us/graph/api/resources/sharinglink?view=graph-rest-1.0
- https://learn.microsoft.com/en-us/graph/api/resources/permission?view=graph-rest-1.0
- https://learn.microsoft.com/en-us/graph/throttling
- https://learn.microsoft.com/en-us/graph/versioning-and-support
- https://learn.microsoft.com/en-us/powershell/azure/active-directory/overview?view=azureadps-2.0
- https://techcommunity.microsoft.com/blog/microsoft-entra-blog/action-required-msonline-and-azuread-powershell-retirement---2025-info-and-resou/4364991
- https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/retirement-announcement-for-azure-acs
- https://learn.microsoft.com/en-us/sharepoint/dev/sp-add-ins/retirement-announcement-for-add-ins
- https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals
- https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/user-admin-consent-overview
- https://learn.microsoft.com/en-us/entra/fundamentals/users-default-permissions
- https://learn.microsoft.com/en-us/graph/api/oauth2permissiongrant-list?view=graph-rest-1.0

## À lire ensuite

- [Liens de partage anonymes Microsoft 365 : comment auditer vos partages externes SharePoint](/blog/fr/trouver-liens-partage-anonymes-microsoft-365)
- [Agents IA et sécurité Microsoft 365 : la nouvelle surface d'attaque à auditer](/blog/fr/agents-ia-microsoft-365-surface-attaque)
- [SharePoint Advanced Management est inclus avec Copilot : ce qu'il couvre, et ce qu'il ne voit pas](/blog/fr/sharepoint-advanced-management-inclus-copilot-limites)

