Find Entra Service Principals With No Sign-in Activity In The Last 30 Days

In Microsoft Entra ID, service principals are widely used by applications, integrations, and automation workflows. However, over time, many service principals may become inactive or unused.

Service principals with no sign-in activity for an extended period can indicate:

  • Unused or abandoned applications
  • Deprecated integrations
  • Security risks due to forgotten identities

👉 Identifying such inactive service principals is crucial for:

  • Reducing attack surface
  • Cleaning up unused identities
  • Strengthening governance

This script helps administrators identify Entra service principals with no sign-in activity in the last 30 days and export the results for review.

🚀 Community Edition Released!

Try the M365Corner Microsoft 365 Reporting Tool — your DIY pack with 20+ out-of-the-box M365 reports for Users, Groups, and Teams.

The Script

                            
# Connect to Microsoft Graph
Connect-MgGraph -Scopes Application.Read.All, AuditLog.Read.All

Write-Host "Scanning Service Principals with NO sign-in activity (last 30 days)..." -ForegroundColor Cyan

# Define timeframe
$Days = 30
$StartDate = (Get-Date).AddDays(-$Days)

# Get all service principals
$ServicePrincipals = Get-MgServicePrincipal -All -Property Id,DisplayName,AppId,Tags

# Get sign-in logs for timeframe
$SignIns = Get-MgAuditLogSignIn -Filter "createdDateTime ge $($StartDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))" -All

# Extract SP AppIds that have activity
$ActiveSPs = $SignIns |
    Where-Object { $_.AppId } |
    Select-Object -ExpandProperty AppId -Unique

$Results = @()

foreach ($SP in $ServicePrincipals) {

    # Exclude Microsoft apps (optional but recommended)
    if (
        $SP.Tags -contains "WindowsAzureActiveDirectoryIntegratedApp" -or
        $SP.Tags -contains "MicrosoftApplication"
    ) {
        continue
    }

    # Check if SP has NO activity
    if ($ActiveSPs -notcontains $SP.AppId) {

        # Console output (minimal)
        Write-Host "$($SP.DisplayName) | $($SP.AppId)" -ForegroundColor Yellow

        # Export object
        $Results += [PSCustomObject]@{
            DisplayName        = $SP.DisplayName
            ServicePrincipalId = $SP.Id
            AppId              = $SP.AppId
            LastSignInStatus   = "No sign-in activity in last $Days days"
            RiskLevel          = "Review Required"
        }
    }
}

# Export results
$ExportPath = "C:\Path\SP_NoSignInActivity_Report.csv"

$Results | Export-Csv $ExportPath -NoTypeInformation

Write-Host "Report exported to $ExportPath" -ForegroundColor Cyan


How the Script Works

Step Description
Connect to Graph Authenticates using Application.Read.All and AuditLog.Read.All
Define Timeframe Sets the last 30 days as the activity window
Fetch Service Principals Retrieves all service principals
Fetch Sign-In Logs Retrieves sign-in logs within the defined timeframe
Extract Active SPs Collects AppIds that have recorded activity
Exclude Microsoft Apps Skips Microsoft-managed service principals
Identify Inactive SPs Filters service principals not found in active list
Build Report Stores inactive SP details in structured format
Export Results Exports report to CSV

Further Enhancements

Enhancement Description
Include Last Sign-In Date Capture actual last sign-in timestamp
Combine With Owner Info Identify inactive SPs with no owners
Add Permission Analysis Include permissions to assess risk
Extend Timeframe Allow custom timeframe input
Auto Cleanup Flag Mark candidates for deletion or review

Frequently Asked Questions

Question Answer
What does “no sign-in activity” mean? No authentication activity recorded in the last 30 days
Are inactive service principals risky? Yes, they may be unused but still hold permissions
Why exclude Microsoft apps? They are system-managed and expected to behave differently
Can logs be incomplete? Yes, depending on retention and licensing
Should inactive SPs be deleted? Only after verifying they are no longer required

Admin Usecases

Use Case Description
Security Audit Identify unused identities
Cleanup Activity Remove stale service principals
Governance Review Ensure active usage of identities
Risk Reduction Reduce attack surface
Compliance Reporting Track identity activity and lifecycle

Possible Errors & Solutions

Error Cause Solution
Insufficient privileges Missing permissions Use Application.Read.All and AuditLog.Read.All
No sign-in data returned Log retention limits Verify audit log retention settings
Cmdlet not recognized Graph module missing Install using Install-Module Microsoft.Graph
Slow execution Large log dataset Apply additional filtering if needed
Empty results No inactive SPs found Verify timeframe or tenant activity

Conclusion

Service principals with no sign-in activity over extended periods are often overlooked but can represent unused or forgotten identities with potential access to sensitive resources.

This Microsoft Graph PowerShell script provides a simple way to identify inactive service principals and export them for review. By incorporating this into regular audits, administrators can:

  • Improve identity lifecycle management
  • Reduce unnecessary access
  • Strengthen overall security posture

Regular monitoring ensures your Entra environment remains clean, secure, and well-governed.

Graph PowerShell Explorer Widget

20 Graph PowerShell cmdlets with easily accessible "working" examples.


Permission Required

Example:


                            


                            


                            

© Created and Maintained by LEARNIT WELL SOLUTIONS. All Rights Reserved.