Browse all topics
Microsoft Entra (Identity)

Cleaning up unused enterprise apps in Entra ID

By Emil Björk · Microsoft ecosystem consultant, Gothenburg

A procedure for finding the service principals nobody uses any more — sign-in activity, credentials, assignments — deciding what is safe to remove, removing it without breaking the one integration that only runs at year end, and keeping the list short afterwards.

Open Enterprise applications in a tenant that is more than a few years old and the count is in the hundreds. A handful are the SaaS products the organisation actually uses. The rest are the residue of every trial, every consultant's demo, every "let me just connect this" from a user, and the automatic service principals Microsoft creates for its own services. Each is an identity with permissions. Most do nothing; a few are quietly holding Directory.Read.All from 2021. Cleaning them up is unglamorous and it is one of the higher-value hours an identity admin can spend.

The distinction between app registrations and enterprise apps (service principals) is in app registrations and enterprise apps; this runbook works on the service principal side, because that is where permissions live.

Step 1: get the whole list with signals

The portal shows the list; it does not show usage. Pull it with Graph, adding the fields that decide what happens next:

Connect-MgGraph -Scopes "Application.Read.All","AuditLog.Read.All","Directory.Read.All"
Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,ServicePrincipalType,AccountEnabled,CreatedDateTime,AppOwnerOrganizationId,Tags,PasswordCredentials,KeyCredentials |
  Select-Object DisplayName, AppId, ServicePrincipalType, AccountEnabled, CreatedDateTime, AppOwnerOrganizationId,
    @{n="Creds";e={$_.PasswordCredentials.Count + $_.KeyCredentials.Count}} |
  Export-Csv .\sps.csv -NoTypeInformation

Then join it to usage. Two sources:

  • Service principal sign-ins (app-only authentication with the SP's own credential): Entra → Sign-in logsService principal sign-ins, or Get-MgAuditLogSignIn -Filter "signInEventTypes/any(t: t eq 'servicePrincipal')". Thirty days of retention with P1/P2; more if you stream to Log Analytics.
  • User sign-ins to the app (a person signing in through the app, delegated): the interactive and non-interactive logs, filtered by application ID. The Usage & insightsApplication activity report summarises this per app for the last 30 days, and the Graph reports/getAzureADApplicationSignInSummary endpoint returns it in bulk.

The Entra ID recommendations page has a Remove unused applications recommendation that does this correlation for you for apps with no sign-ins in the recent window, and a companion Remove unused credentials from applications. Start there if you want a first pass in five minutes; use the export above for the real job.

Step 2: sort into piles

Every service principal falls into one of these, and the action is different for each.

Microsoft first-party. AppOwnerOrganizationId is Microsoft's tenant ID (the well-known f8cdef31-a31e-4b4a-93e4-5f571e91255a), or the SP carries WindowsAzureActiveDirectoryIntegratedApp in its tags. Leave these alone. They are how Microsoft 365 services talk to each other, and deleting one produces baffling failures with no obvious cause. The exception is a first-party SP with user consent grants you want to revoke — that is a permissions question, handled in over-consented app cleanup, not a deletion.

Gallery and SAML apps with no sign-ins. The SaaS app that was piloted and dropped. Usually safe to remove once you have confirmed with whoever owned the pilot. Check whether it has user assignment required and assigned users — that tells you who thought they were using it.

Multi-tenant apps consented from elsewhere. AppOwnerOrganizationId is some other tenant. These are vendor integrations and user-consented add-ins. No sign-ins for a long period and no credentials in your tenant means nothing on your side can be using it; the vendor's side may still hold a token. Removing the SP revokes every consent and token, which is the point.

Your own app registrations' service principals. Home tenant is yours. No sign-ins, but credentials exist and someone's script may hold them. These are the ones where the sign-in log is decisive: no app-only sign-ins in 90 days, and no user sign-ins, means nothing is authenticating. Check the owners field and ask them.

Managed identities. ServicePrincipalType is ManagedIdentity. Their lifecycle follows the Azure resource; delete the resource, not the SP.

Disabled SPs. AccountEnabled false. Someone disabled it as a step toward deleting it and never finished. Confirm nothing has complained since, then delete.

Step 3: remove safely

For each candidate in the removable piles:

  1. Record it. Display name, AppId, permissions granted (Get-MgServicePrincipalOauth2PermissionGrant and Get-MgServicePrincipalAppRoleAssignedTo), owners, and the date. Deletion of a service principal is recoverable for 30 days from Entra's deleted items; the record is what lets you decide to recover it without re-investigating.
  2. Disable first, delete later. Set AccountEnabled to false, wait a period that covers the integration's likely schedule — a month catches monthly jobs, and the year-end report is the classic surprise — then delete. A disabled SP fails loudly when something uses it, which is exactly the signal you want.
  3. Delete with Remove-MgServicePrincipal. If the app registration is also yours and also unused, delete that too, otherwise the SP regenerates the next time someone consents.
  4. Watch the sign-in log's failures for the AppId over the following week. Anything that shows up is your missed consumer.

Do this in batches of ten or twenty, not two hundred at once. The point of the disable-then-delete gap is that you can attribute a failure to a batch.

Step 4: keep it short

  • Restrict user consent so users cannot add multi-tenant apps to the tenant without review; the app consent policies guide covers the admin consent workflow that replaces it.
  • Require an owner on every registration and service principal. Ownerless apps are the ones that rot. A quarterly report of ownerless SPs, sent to the identity team, keeps the list honest.
  • Access reviews for applications, if you have Entra ID Governance, to push the "do you still use this?" question to the app owners on a schedule instead of to you.
  • Alert on new service principal creation outside your process. In a tenant with consent restricted, a new SP appearing is either a planned change or an incident.

What needs support or downtime

Neither. The risk is entirely deleting something in use, which the disable-first gap converts from an outage into a failed job someone notices — and the 30-day recovery window converts that into a five-minute restore. The one thing to avoid without exception is deleting Microsoft's own service principals; that is where support engagement begins, and it is avoidable.

Further reading

Spot something wrong or want a topic covered? Send it through the contact form.