Skip to content
Menu
Tech Automation Blog
  • About Author
  • Contact
Tech Automation Blog

Azure AD application Certificate expiration report

Posted on November 8, 2019February 27, 2022

Update : updated script to support Azure Az powershell module.

Once we register an Application with Azure AD, we configure Secrets or Certificates or sometimes both. This is required to set up application authentication and authorization, Sign-On or OAuth authorization service etc.

The secret or the certificate we set on the application has an expiry. Once it is expired, it can not be used. It can cause unwanted downtime, if we miss to renew certificate or secret with new value after it has expired. It is very critical that we get notified before it expires and we renew it in time.

I provided a script to generate a list of all Azure AD Application along with expiration in my previous blog. Today, I sharing a script which will notify you on expired or expiring Certificate.

Before we start, we need an Azure AD user account with rights to read AD Application details. Script will retrieve the credentials from Key Vault. Along with credentials, you need an SMTP server or a Relay to send emails through it. Also, you need AzureAD, Az powershell module installed and imported in to your powershell console.

Once you have those prerequisites set up, login to Azure using Login-AzAccount. Provides your credentials when prompted.

This image has an empty alt attribute; its file name is image-17.png

Alternatively, if you are configuring this script as an automation run book, use below code block to login to Azure using the Service Principal configured for the Automation RunAs account.

#region - login to Azure from the Automation Account
$connectionName = "AzureRunAsConnection"
try{
    $servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
    "Logging in to Azure..."
    Add-AzAccount `
        -ServicePrincipal `
        -TenantId $servicePrincipalConnection.TenantId `
        -ApplicationId $servicePrincipalConnection.ApplicationId `
        -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch{
    if(!$servicePrincipalConnection){
        $errorMessage = "Connection $connectionName not found"
        throw $errorMessage
    }else{
        Write-Error -Message $_.Exception
        throw $_.Exception
    }
}
#endregion

Now, let’s define a variable for the number of days for the certificate expiry check. Here I am using 7 days. You may change this number to whatever value you want to check before considering the certificate renewal.

$daysToExpire = 7

Next, define a variable for the Key Vault name where you have stored your Azure AD user id and password to use to login to Azure AD.

#region - Retrieve Azure AD Service Account Credentials from Key Vault
$kvName = <Your Key Vault Name>
$azADSvcAcc = (Get-AzureKeyVaultSecret -VaultName $kvName -Name AzureADSvcAccount).SecretValueText
$azADSvcAccPwd = (Get-AzureKeyVaultSecret -VaultName $kvName -Name AzureADSvcAccountPassword).SecretValueText
$password = ConvertTo-SecureString $azADSvcAccPwd  -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ($azADSvcAcc, $password)
#endregion

Next, check if AzureAD powershell module is already imported. If not, import it as shows below:

#region - import AzureAD Module if it is not already imported and then connect to Azure AD
if((Get-Module -Name AzureAD).count -gt 0){
    Write-Output "Azure AD Module is already imported"
}else{
    Write-Output "Azure AD Module is missing. Importing Module."
    Import-Module AzureAD -Force
}
Connect-AzureAD -Credential $Cred
#end - region

Now, define an array variable to store application details and mail details – including sender email, recipient email, SMTP server and port Number.

$allApplications = @()
$mailFrom = <Email id of the sender - it could be a fake email>
$mailTo = <Email id of recipient>
$subject = "AzureAD App Certificates Expired/Expiring in $daysToExpire days"
$smtpserver = <SMTP Server FQDN / IP Address>

Once we have all required variables set up, we will start parsing through each Azure AD application.

#region - Check Azure AD Applications and adds to an array defined earlier
Get-AzureADApplication -All $true | ForEach-Object{
    $applicationName = $objectType = $objectId = $applicationId = $keyId = $certExpirationDate = ""
    $certExpired = $certExpiring = "False"
    $owner = ""
    $applicationName = $_.DisplayName
    $objectType = $_.ObjectType
    $objectId = $_.ObjectId
    $applicationId = $_.AppId
    $owner = (Get-AzureADApplicationOwner -ObjectId $objectId).DisplayName
    $certCreds = (Get-AzureADApplication -ObjectId $objectId).KeyCredentials
    if(!([String]::IsNullOrEmpty($certCreds))){
        $certCreds | ForEach-Object{
            $keyId = $_.KeyId
            $certExpirationDate = $_.EndDate
            if($certExpirationDate -lt (Get-Date)){
                $certExpired = "True"
                $certExpiring = "N/A"
            }
            elseif($certExpirationDate -le (Get-Date).AddDays($daysToExpire)){
                $certExpiring = "True"
            }
            if($certExpired -ne "False" -and $certExpiring -ne "False"){
                $objCert = New-Object psobject
                $objCert | Add-Member ApplicationName $applicationName
                $objCert | Add-Member ApplicationId $applicationId
                $objCert | Add-Member ObjectType $objectType
                $objCert | Add-Member Owner $owner
                $objCert | Add-Member KeyId $keyId
                $objCert | Add-Member CertExpirationDate $certExpirationDate
                if($certExpired){$objCert | Add-Member CertExpired $certExpired}
                if($certExpiring){$objCert | Add-Member CertExpiring $certExpiring}
                $allApplications += $objCert
            }
        }
    }    
}
#endregion

At this point, we have required data to process. Let’s start working on the presentation of data in to a nice looking table and attach it to the body of the email.

#region - create Table and its schema
$table = New-Object system.Data.DataTable "certReportTable"
$col1 = New-Object system.Data.DataColumn "Application Name",([string])
$col2 = New-Object system.Data.DataColumn "Application Id", ([string])
$col3 = New-Object system.Data.DataColumn "Object Type", ([string])
$col4 = New-Object system.Data.DataColumn "Owner", ([string])
$col5 = New-Object system.Data.DataColumn "Key Id", ([string])
$col6 = New-Object system.Data.DataColumn "Expiration Date", ([string])
$col7 = New-Object system.Data.DataColumn "Cert Expired?", ([string])
$col8 = New-Object system.Data.DataColumn "Expiring in $($daysToExpire) days?", ([string])
#Add colums to table
$table.Columns.Add($col1)
$table.Columns.Add($col2)
$table.Columns.Add($col3)
$table.Columns.Add($col4)
$table.Columns.Add($col5)
$table.Columns.Add($col6)
$table.Columns.Add($col7)
$table.Columns.Add($col8)

#populate table with data
foreach ($app in $allApplications){
    $row = $table.NewRow()
    $row."Application Name" = $app.ApplicationName
    $row."Application Id" = $app.ApplicationId
    $row."Object Type" = $app.ObjectType
    $row."Owner" = $app.Owner
    $row."Key Id" = $app.KeyId
    $row."Expiration Date" = $app.CertExpirationDate
    $row."Cert Expired?" = $app.CertExpired
    $row."Expiring in $($daysToExpire) days?" = $app.CertExpiring
    $table.Rows.Add($row)
}
#endregion

Finally, we will work on setting up the HTML email body formatting and send the email as shown below:

#region - set HTML CSS values, HTML body and send email
$header = @"

<style>
  body {
    font-family: "Arial";
    font-size: 8pt;
    color: #4C607B;
    }
  th, td { 
    border: 1px solid #e57300;
    border-collapse: collapse;
    padding: 5px;
    }
  th {
    font-size: 1.2em;
    text-align: left;
    background-color: #003366;
    color: #ffffff;
    }
  td {
    color: #000000;
    }
  .even { background-color: #ffffff; }
  .odd { background-color: #bfbfbf; }
</style>

"@

[string]$body = [PSCustomObject]$table | Select-Object -Property "Application name","Application Id","Object Type","Owner","Key Id", "Expiration Date", "Cert Expired?", "Expiring in $($daysToExpire) days?" | Sort-Object -Property "Application Name"  | ConvertTo-HTML -head $header -Body "<font color=`"Black`"><h4>AzureAD Application Certificate Expired/Expiring in $daysToExpire days</h4></font>" 


#Send email to stake holders
$mailMessageParameters = @{
	From       = $mailFrom
	To         = $mailTo
	Subject    = $subject
	SmtpServer = $smtpserver
	Port	   = 25
	Body       = $body
}
Send-MailMessage @mailMessageParameters -BodyAsHtml
#endregion

Great! we are all set now. Run the script and expect an email with all required details in a nicely formatted table. You can schedule it to run in a certain interval by either configuring it through Scheduled Task or a Schedule in Automation account.

Provide your comments in the comment section of this page. You can contact me if you face any issue with this script.

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on LinkedIn (Opens in new window) LinkedIn
May 2025
M T W T F S S
 1234
567891011
12131415161718
19202122232425
262728293031  
« May    

Recent Posts

  • Monitor and alert Azure Service Health issues May 5, 2020
  • AWS IAM User access review May 3, 2020
  • Integrate Azure Security Center with Event Hub April 28, 2020
  • Add Tags to Azure Subscription April 24, 2020
  • Automate Azure billing report in Excel March 6, 2020

Categories

©2025 Tech Automation Blog | Powered by SuperbThemes