Find stale Enterprise Applications – Entra ID

If you’ve recently restricted user registration for applications or are analyzing your Enterprise applications, you might find a significant amount of work ahead.
First, you may want to find if there are applications with no user assigned. Then you may wonder if there are applications without sign-ins in the last 30 days.

To ease your work, you may find it useful to query all applications for these fields and get the output in a CSV. This script is based on Ravenswood PoC code, with the intent of helping out and refining it a bit.

First, head to Enterprise Applications | AAD and click “Download (Export)”, then download the CSV.

This is done via the portal and not via PowerShell for practicality. If you are not interested in reviewing Microsoft Applications, filter the csv file to just keep “Enterprise Application” under applicationType. This will greatly improve the processing time.

Then save the following script in the same directory where you downloaded the EnterpriseAppsList.csv. Name the script StaleApplicationAnalysis.ps1.

The script will require AzureADPreview.
Update 2024: The script does not detect non-interactive sign-ins. To detect non-interactive sign-ins, Get-MgAuditLogSignIn should be used. I have not modified this script yet to use Graph.

# Connect to Azure AD
# Check if AzureAD module is installed
if (-not (Get-Module -Name AzureADPreview -ListAvailable)) {
    Write-Host "AzureADPreview module is not installed. Installing..."
    Install-Module -Name AzureADPreview -Force
}
 
# Import AzureAD module
try {
    Import-Module -Name AzureADPreview -ErrorAction Stop
    Write-Host "AzureADPreview module imported successfully."
} catch {
    Write-Host "Failed to import AzureADPreview module: $_" -ForegroundColor Red
}
 
Connect-AzureAD
 
$AllApplications = Import-Csv .\EnterpriseAppsList.csv
$Output = @() # Array to store output objects

foreach ($Application in $AllApplications) { 
    # Retrieve the objectid and signin logs, format the user assigned to the app 
    $app = Get-AzureADServicePrincipal -All $true | where { $_.objectid -eq $application.id }
    $Log = Get-AzureADAuditSignInLogs -All $true -Filter "appid eq '$($App.AppID)'"
 
    $userassigned = Get-AzureADServiceAppRoleAssignment -ObjectId $App.ObjectId | Select ResourceDisplayName, PrincipalDisplayName
    $userCount = 0
    if ($userassigned -ne $null) {
        $format = $userassigned.GetType()
        if ($format.basetype.name -eq "Object") { 
            $userassigned = [string]$userassigned
        }
        $userCount = $userassigned.Count;
    }
    # Create a custom object for output 
    $Table = [PSCustomObject]@{ 
        ApplicationName = $App.DisplayName 
        ApplicationID = $App.AppID 
        SignIns = $Log.Count
        Users =  $userCount
    }
    $Output += $Table
    $Table
    Start-Sleep 4 # The sleep is to avoid throttling
}

# Export the output to CSV
$Output | Export-Csv -Path .\StaleApplicationCleanup.csv -NoTypeInformation

And finally, run the script. This will take a bit of time since I had to implement a sleep timer to prevent throttling.

.\StaleApplicationAnalysis.ps1

The output will be along these lines, with an additional column for the App ID:

If you happen to find any optimization, feel free to let me know, and I’ll update the post.

8 thoughts on “Find stale Enterprise Applications – Entra ID

  1. The command is included in AzureADPreview. My best guess would be that you are not using the preview version.
    Try either cleaning up the modules or installing AzureADPreview in a different powershell 🙂

    Like

  2. No problem 🙂

    By default with this query you are looking at the last 30 days logs, which is as far as the default retention will get you.
    If you want to query the last 15 days you might use a filter after Get-AzureADAuditSignInLogs. Something like
    Get-AzureADAuditSignInLogs -Filter “createdDateTime gt 2024-01-15”
    will fetch the sign-in logs that were created after January 15, 2024.

    For the filter in csv. You’ll need to copy paste the filtered results overwriting the original text. This way it’ll process only the Enterprise Apps.

    Like

  3. Am I missing something? I keep getting this error. “The term ‘Get-AzureADAuditSignInLogs’ is not recognized as the name of a cmdlet”

    Like

  4. Thanks Pietro, much appreciated!

    This script works for me now but I do have one question.

    It’s probably something really simple I may have missed, but how can I change the script to look for applications without sign-ins over the last X number of days?

    Also is there any way to filter just Enterprise Applications? I’ve tried doing it through the CSV like you mentioned but that’s only a visual change as the script still processes the entire CSV.

    Like

Leave a comment