Powershell script to audit all Azure AD app registrations and notify secret key or certificate expiration

This week, I have another real-time use case about the audit of all azure AD app registrations and notify the application credential (secret key or certificate) near to expiration.

Registering an application in Azure AD establishes a trust relationship between your app and the Microsoft identity platform, The application registration can be used to authenticate on behalf of a user and request access to resource applications.

I was asked to have a mechanism to monitor the azure ad app registrations and notify the app owner (if exist) if the secret key or certification expiration is nearby (x days).

When I started off looking for a solution, I have found a couple of articles on this but they are all making use of graph API, power automation, etc.

I don't have any of these enabled such as power automate, power logic, graph API, etc. in my tenant, (can it be enabled, sure why not).

So I thought to make use of the native Powershell script with built-in Azure AD Powershell module and report the application credential expiration info.

I have found a Microsoft article that refers to the exact requirement that I was looking for. The native Powershell script using the Azure AD Powershell module https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/scripts/powershell-export-all-app-registrations-secrets-and-certs

I have used this script and customized it according to my needs. You can run this script with the least privileged account such as a global reader.

The custom requirement that I had was, to monitor the app registration secret key or certificate that is near to expiry (30 days) and send an email to the application owner. If no application owner not found or a common function account is used to create the app, then email to the team who can follow up for further action on it.

It is always secure that, office 365 admin/team doesn’t let the application team create the app registration, and instead, Azure AD Application admin or someone with enough permissions will create the app registration and provide the app details to the application team.

During this process, if you don’t add the application team (DL is preferred) info in the application properties, the owner of the application will be the account that is used to create the app.

Say, for example, I have an account (fid0365@eskonr.com) that is used to create the app registration on behalf of the application team, this account will be the owner unless I add the application team DL into the application properties for email notification.

The script provided in the Microsoft article nicely exports all the applications that are expired or near to expiry with owner info and other details.

we will make use of this output file and process it and notify via email in case any applications are near expiry.

The following is the piece of code that I have added to the original script to meet the requirement.

$CutoffDate = (get-date).AddDays(30)
if ($Logs)
$Data=Import-Csv $outfile | Where-Object {($_.'Secret End Date' -as [datetime] -lt $CutoffDate -and $_.'Secret End Date' -ne '') -or ( $_.'Certificate End Date' -as [datetime] -lt $CutoffDate -and $_.'Certificate End Date' -ne '')}
foreach ($d in $data)
$secretend1=$d.'Secret End Date'
$certend1=$d.'Certificate End Date'
By default, if you use function or any other standard account to create the app registration, the account will be stamped as the the owner.
if your org allows user to create their own or follow the process to create the app onbehalf users, then this account will be common for all apps.
In Such cases, you may have to improve the process to update the app owner info with the Distribution list or user name so that when the app is near expiry, a notification will be sent.

if($d.Owner -eq 'fid0365@eskonr.com' -or $d.Owner -eq $null ) {$Owner1="eswar.kon@eskonr.com"}
$From = “MonitorApps@eskonr.com
$smtp="SMTP details"
$To = $Owner1
$Subject = "Your o365 app secret key or cert is expiring in the next 30 days"
$Body = "Hi,
we have identified that, you are the owner of the app:$appname1 created in Azure AD and its secret key or certificate expiring in the next 30 days.

Please review, renew the application. If the application is not used anymore, please raise a request to decom/remove the application from Azure AD portal.

The following are the details of Secret Key and Certificate
Secret Key Expiration Date=$secretend1
Certificate End Date=$certend1

Ignoring the messages may cause your application not function properly.

xxxxx Team
P.S: This is automated generated email. Please do not respond to this email.
Send-MailMessage -From $From -To $To -SmtpServer $smtp -Subject $Subject -Body $Body

I have uploaded the full script to GitHub incase you would like to customize!

4 Responses to "Powershell script to audit all Azure AD app registrations and notify secret key or certificate expiration"

  1. Hi Wendy,

    Kindly help with your working solution model of notifying the secret keys that is already expired & about to expire in 45 days that you setup please?

    1. Hi,
      the powershell script that i posted should help you to trigger an email alert based on the script run without using any azure automation.
      you can also use azure automation to schedule and notify if the secret key expire in the next 45 days or so.
      have you tried the script posted in the blog post?


  2. Has anyone figured out how to export the secret key description yet? I have this solution, all set up with automation, to notify us of the keys expiring within the next 45 days. It pulls many properties, such as start, end date, owner, id's etc. However, if you look at the app registration secret in azure- you will see there is an optional "description" , I have tried to pull this with powershell with no luck. The reason its important is because, application proxy secrets renew themselves, so we don't care if they are expiring. The app proxy secrets always have a description of "CWAP_AuthSecret". If I could access that property, I could filter them out. Unless there is a better way to filter those out!

    1. @Wendy
      The CustomKeyIdentifier is the property your were looking for.
      CustomKeyIdentifier : {67, 87, 65, 80...}
      EndDate : 20.10.2023 19:32:22
      KeyId :
      StartDate : 20.10.2022 19:28:22
      Value :

      [char[]]$Secret.CustomKeyIdentifier -join ''
      converts the ASCII Characters to "CWAP_AuthSecret"
      Regards, Alex


Leave a Reply