To find unused applications in Microsoft Entra ID, read each enterprise application's last sign-in from the service principal sign-in activity report and keep those with none in the period you choose. The report needs Microsoft Entra ID P1 or P2 and is in preview, on the beta Microsoft Graph endpoint. Its last activity can include partial sign-ins, so a recent date alone doesn't prove the app was used.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of apps and managed identities with no sign-in in 180 days or ever. |
| Admin centre | A look at 1 app's last activity, or a short list of apps. |
| Altivane | Recommended for recurring reviews, with each app's granted permissions on the same row. |
Before you start
Use an account in the Reports Reader, Security Reader or Security Administrator role to read the sign-in activity. The tenant needs Microsoft Entra ID P1 or P2. The PowerShell example requests Application. and AuditLog.; your organisation may require administrator consent.
Know what the data says. The report gives each app's most recent sign-in, whether it signed in as a client or was called as a resource, with a user or on its own. An app with no sign-in recorded has no entry. The examples leave out the apps Microsoft owns. They read and export; they don't disable or delete any app.
Option 1
Find unused applications with PowerShell
Install the modules once, then connect, read the sign-in activity and export the apps with no sign-in in the period.
# Install once, if the modules are not already installed.
$modules = 'Microsoft.Graph.Authentication', 'Microsoft.Graph.Applications',
'Microsoft.Graph.Beta.Reports'
Install-Module $modules -Scope CurrentUser$ErrorActionPreference = 'Stop'
Connect-MgGraph -Scopes 'Application.Read.All', 'AuditLog.Read.All' -NoWelcome
try {
$days = 180
$cutoff = (Get-Date).ToUniversalTime().AddDays(-$days)
# The 2 tenants that own Microsoft's apps.
$microsoft = 'f8cdef31-a31e-4b4a-93e4-5f571e91255a', '72f988bf-86f1-41af-91ab-2d7cd011db47'
$lastSignIn = @{}
Get-MgBetaReportServicePrincipalSignInActivity -All | ForEach-Object {
$lastSignIn[$_.AppId] = $_.LastSignInActivity.LastSignInDateTime
}
$properties = 'id', 'appId', 'displayName', 'servicePrincipalType',
'appOwnerOrganizationId', 'accountEnabled'
$apps = @(Get-MgServicePrincipal -All -Property $properties | Where-Object {
$_.ServicePrincipalType -in 'Application', 'ManagedIdentity' -and
$_.AppOwnerOrganizationId -notin $microsoft
})
$report = @(foreach ($app in $apps | Sort-Object DisplayName) {
$last = $lastSignIn[$app.AppId]
if ($last -and $last.ToUniversalTime() -ge $cutoff) { continue }
[pscustomobject]@{
Application = $app.DisplayName
Type = $app.ServicePrincipalType
Enabled = $app.AccountEnabled
LastSignIn = $last
AppId = $app.AppId
}
})
if ($report.Count -eq 0) {
Write-Output "Every application signed in within the last $days days."
} else {
$report | Export-Csv -Path './unused-applications.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($report.Count) of $($apps.Count) applications are unused."
}
} finally {
Disconnect-MgGraph | Out-Null
}The script reads the sign-in activity once, then keeps every application and managed identity not owned by Microsoft whose last sign-in is older than 180 days or missing. LastSignIn is blank for an app with no sign-in recorded. Change $days for another period. An unused app can still hold permissions, so check what it was granted before you remove it.
Check 1 application
Reconnect with Connect-MgGraph, then read 1 app's activity by its application ID.
# Run while connected to Microsoft Graph. Replace the example application ID.
$filter = "appId eq '00000000-0000-0000-0000-000000000000'"
Get-MgBetaReportServicePrincipalSignInActivity -Filter $filter |
Select-Object AppId, LastSignInActivity, DelegatedClientSignInActivity,
ApplicationAuthenticationClientSignInActivityEach activity has its own LastSignInDateTime, so you can tell an app that signs in with users from one that signs in on its own.
Option 2
Review app activity in the admin centre
- Sign in to the Microsoft Entra admin centre for the correct tenant as at least a Reports Reader.
- Go to Entra ID > Monitoring & health > Usage & insights.
- Select Service principal sign-in activity (preview) to see the last activity date for each service principal.
- Select View more details on a row for the app's client and object IDs and how it signed in.
- To see 1 app's sign-ins by day, select Microsoft Entra application activity (preview), then View sign-in activity for the app.
This suits a look at 1 app or a short list. The page doesn't mark an app as unused or show what it was granted, so for a list to act on, use PowerShell or a report.
Option 3 ยท Recommended for recurring reviews
Report on unused applications with Altivane
- Open Altivane and choose the tenant.
- Build the tenant's documents with the Applications scorecard report in full, so the apps are listed as well as counted.
- Open the tenant's Excel workbook and find Unused Applications: each enterprise application and managed identity, other than Microsoft's own, with no sign-in in 180 days or ever, with its type, owner tenant, whether it is enabled, when it was created, its last sign-in, the days since and the application permissions granted to it.
- Read Application Summary for the count and whether sign-in activity was available.
Altivane reads the same sign-in activity, so the same licence applies: without Microsoft Entra ID P1 or P2 the count says Not licensed and the table is left out, and where the activity can't be read the count says Not read rather than 0. The 180 days is the same period after which user accounts count as stale, so apps and accounts age alike. The table goes to the workbook only to start; you can put it in the Word report too.
Contact usCommon questions
Is an app with no recent sign-in safe to delete?
Not always. An app used once a year, or one that waits to be called, can look unused. Check its owner and its permissions first; see how to review app permissions. A deleted app registration can be restored for 30 days.
Why doesn't a recent date prove the app works?
Microsoft says last activity can include partial sign-ins and other incomplete activity that isn't in the sign-in logs. A date alone doesn't show that the sign-in completed or that a token was issued.
Why does the report return an error or nothing at all?
Check the licence and the role first: the report needs Microsoft Entra ID P1 or P2 and 1 of the reader roles above. It's a beta API, available in Microsoft's global service and not in the US Government or China clouds.
Microsoft references
Technical references checked on 7 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.