Azure AD Enterprise Application Cleanup

Any large organization knows that the number of applications tied to their identity provider can quickly become difficult to manage. As an organization’s number of enterprise application integrations increases, the Azure Active Directory (AD) Admin Portal quickly becomes less usable.

By default, the Admin Portal shows the last 7 days of sign-ins for each app. Navigating through all the enterprise applications to look at sign-in logs is unwieldy. For most large tasks, using the Admin Portal isn’t very helpful.

For example, consider all the apps shown in Figure 1. Are they even in use anymore? Going through each app to look at the sign-in logs would take an inordinate amount of time. The collection of apps in Figure 1 is nowhere near what most organizations would have, but even in a lab environment you can see how difficult it would be to go through each app.

Review which Azure AD enterprise applications are in use
Figure 1 – Review which Azure AD enterprise applications are in use

So how do we get this situation under control? Scripting to the rescue!

What do we need?

Our goal is to determine whether an application has been used recently to see if we can remove it. We can use the PowerShell command Get-AzureADAuditSignInLogs to obtain this information. However, Azure sign-in logs are kept for only 30 days, so another method may need to be used for longer retention, such as logging to an Azure storage account or connecting Azure Active Directory to Microsoft Sentinel. You can also use Azure Sentinel’s Log Analytics to query the data.

For the purposes of this article, we focus on existing logs and how we achieve our goal.

At the time of this writing, the Get-AzureADAuditSignInLogs argument is only available in the AzureADPreview PowerShell module. Before installing or updating this module, check to see if Get-AzureADAuditSignInLogs is included in the generally available AzureAD module. We can install or update the AzureADPreview module by running Install-Module -Name AzureADPreview or Update-Module -Name AzureADPreview.

Gathering Data

Once we have the AzureADPreview module installed, we connect to Azure AD using Connect-AzureAD. The credentials used to connect will need the ability to read—and if deleting, the ability to modify—enterprise applications. It’s recommended to use the least privilege necessary to complete the task. I’m using an account with the Security Reader role in Azure AD. The Application Administrator role will also allow us to read log information, but limiting to Security Reader will give us much more restricted access.

On to the fun stuff! We need to get a list of our applications. Achieving this is pretty straightforward; run Get-AzureADApplication. This command will provide you with the ObjectID, AppID, and DisplayName of your connected applications that have been registered in your Azure tenant. The Get-AzureADServicePrincipal command returns additional enterprise applications. Let’s put those attributes into a variable for safe keeping: $Apps = Get-AzureADApplication.

From here we can use our fancy new preview command to parse our logs and output data. Note that Microsoft throttles connections when using Get-AzureADAuditSignInLogs. Microsoft also throttles connections for retrieving sign-in logs, so we add a Start-Sleep parameter at the end of the loop to provide a break between applications. The following code is a proof of concept to determine in-use applications and provide some rudimentary reporting:

#To enable verbose [CmdletBinding()] Param() #Retrieve list of applications $Apps = Get-AzureADApplication #Loop through each application ForEach($App in $Apps){ Write-Verbose "Processing $($App.DisplayName)" #Retrieve logs filtered on AppID $Log = Get-AzureADAuditSignInLogs -All $true -filter "appid eq '$($App.AppID)'" #Create a custom object for output [PSCustomObject]@{ ApplicationName = $App.DisplayName ApplicationID = $App.AppID SignIns = $Log.count } #To prevent throttling on Sign-in Log querying, insert a sleep Start-Sleep 1 }
Code language: PowerShell (powershell)

We now have output that we can sort through to determine whether an application has been in use in the past 30 days. This code will return ApplicationName, ApplicationID, and a count of how many sign-ins there have been for each application.

Cleanup

Once we have a list of enterprise applications we want to dispose of, we can use an administrative account with the Application Administrator role to perform cleanup. If there are only a handful of applications, it may be easiest to use the portal and disable or delete applications from there. If automation is desired or if there are a large number of applications to work with, there are a few commands that will help us along the way. We can use the Remove-AzureADApplication and Set-AzureADApplication commandlets. Removing is quite destructive, so we recommend just disabling the application instead. Use Set-AzureADApplication -IsDisabled $true. This gives us the ability to ensure that the application is not in use for however long we’d like to wait before removing it.

Final Thoughts

Although the process of cleaning up your enterprise applications can be quite time-consuming, there are several useful ways to report and manage applications in Azure. Ravenswood Technology Group has the expertise you need to generate valuable reports. We can also help design your enterprise application life cycle for optimal efficiency. Contact our experts today!

WHAT WE DO

Remediating LDAP Client Security

Remediating LDAP security issues is important because the default configurations on domain controllers (DCs) and clients are open to various attacks. Learn how to remediate those issues.

Monitoring for LDAP Client Security

Applications that use Lightweight Directory Access Protocol (LDAP) are prevalent in virtually every organization that uses Active Directory (AD). Unfortunately, the default AD configuration provides

Leave a Comment

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.