Script for getting Azure AD app registration secrets and certificates that expire soon

Just needed to clean up expired app registration secrets from a tenant, and figured I could just make a very quick script to find secrets and certificates that expire soon. Have fun – no explanation needed i guess.

Connect-AzureAD
$expiresWithinDays = 31
$expired = Get-AzureADApplication -All:$true | ForEach-Object {
    $app = $_
    @(
        Get-AzureADApplicationPasswordCredential -ObjectId $_.ObjectId
        Get-AzureADApplicationKeyCredential -ObjectId $_.ObjectId
    ) | Where-Object {
        $_.EndDate -lt (Get-Date).AddDays($expiresWithinDays)
    } | ForEach-Object {
        $id = "Not set"
        if($_.CustomKeyIdentifier) {
            $id = [System.Text.Encoding]::UTF8.GetString($_.CustomKeyIdentifier)
        }
        [PSCustomObject] @{
            App = $app.DisplayName
            ObjectID = $app.ObjectId
            AppId = $app.AppId
            Type = $_.GetType().name
            KeyIdentifier = $id
            EndDate = $_.EndDate
        }
    }
}

$expired | Out-GridView

15 thoughts on “Script for getting Azure AD app registration secrets and certificates that expire soon

  1. Hello Marius, I was wondering if there was an updated version of your script – When just running $expired = Get-AzureADApplication and then displaying the output, it doesn’t contain 3/4 of the app registrations within my tenant. I have put together a script that I keep breaking in powershell 🙂 that almost works but my problem lies where there are multiple certs or secrets for an app registration, it just displays ‘system.object’ instead of the expiration date – my script essentially goes through and displays expired, warning or good based on my threshold (I would share the script but I am trying to piece it back together into a working form) – do you have something newer that will get all app registrations and check for expire/soon to be expired certs and secrets but also accomodate for multiple certs/secrets per app registration?

  2. Hello Marius. First of all, I am a beginner in this field. What I want to do is that I have a list of specific spn’s that contains their object id’s, names, etc. Instead of checking all the spn’s , how can I adapt your script to my purpose? I don’t want the script to detect all the spn’s. only the ones that I chose. I would be grateful if you could help

    1. That is super simple actually. The Get-AzureADApplication cmdlet, now also covered through the Get-MgApplication cmdlet in the Microsoft Graph SDK PowerShell module, has an option -Filter allowing you to search with filters like -Filter “displayName eq ‘Test'” or you can filter client side using Where-Object:

      Get-AzureADApplication -All:$true | Where-Object DisplayName -like “*github*”

  3. Thank you so much! I am hesitant to ask but what if I want to search for two different word in DisplayName. Like an spn that its name contains both ‘abc’ and ‘xyz’

      1. Thank you so much! I would like to ask you something else. I would be grateful if you could take a look.

        I have a list of SPN’s with their DisplayName. What I want to do is to run this exact script for my specific SPN’s.

        Is there any way to retrieve only these DisplayName instead of Get-AzureADApplication -All:$true ?

      2. Yes, but usually it is actually fastes to graph all applications with -All:$true and filter client side. You can for example do this by something as follows:

        # Read apps to check from a csv
        $AppsToCheck = Get-Content -Raw “csvfile.csv” | convertfrom-csv

        # Get all apps where the displayname is in the displayname column in the csv:
        Get-AzureADApplication -All:$true | Where-Object DisplayName -in $AppsToCheck.DisplayName

  4. Hi Marius,

    Script looks great! Have you by chance integrated this on an updated version of PowerShell? Newer versions (Now having to work with Get-AzADApplication) doesn’t appear to recognize the -All param. Also, Get-AzureADApplicationKeyCredential is not available.

Leave a reply to Marius Solbakken Cancel reply