Skip to content

Instantly share code, notes, and snippets.

@svarukala
Last active May 10, 2023 19:38
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save svarukala/64ade1ca6f73a9d18236582e8770d1d4 to your computer and use it in GitHub Desktop.
Save svarukala/64ade1ca6f73a9d18236582e8770d1d4 to your computer and use it in GitHub Desktop.
Outputs list of all Azure AD Apps along with their expiration date, display name, owner email, credentials (passwordcredentials or keycredentials), start date, key id and usage. Useful to know the apps that are expiring and take action (renew). Since Azure AD PowerShell is being deprecated in favor of Microsoft Graph PowerShell SDK, I created a …
# Requires Azure AD PowerShell Module
#Prompts user to login using Azure Credentials
Connect-AzureAD
$results = @()
Get-AzureADApplication -All $true | %{
$app = $_
$owner = Get-AzureADApplicationOwner -ObjectId $_.ObjectID -Top 1
$app.PasswordCredentials |
%{
$results += [PSCustomObject] @{
CredentialType = "PasswordCredentials"
DisplayName = $app.DisplayName;
ExpiryDate = $_.EndDate;
StartDate = $_.StartDate;
KeyID = $_.KeyId;
Type = 'NA';
Usage = 'NA';
Owners = $owner.UserPrincipalName;
}
}
$app.KeyCredentials |
%{
$results += [PSCustomObject] @{
CredentialType = "KeyCredentials"
DisplayName = $app.DisplayName;
ExpiryDate = $_.EndDate;
StartDate = $_.StartDate;
KeyID = $_.KeyId;
Type = $_.Type;
Usage = $_.Usage;
Owners = $owner.UserPrincipalName;
}
}
}
$results | FT -AutoSize
# Optionally export to a CSV file
#$results | Export-Csv -Path "AppsInventory.csv" -NoTypeInformation
@svarukala
Copy link
Author

appslist
This is the sample output from this script. Note that some of the apps can have multiple entries or zero entries as an app can have multiple keys or no keys at all.

@svarukala
Copy link
Author

Updated the script:
a. To get all the ad apps (previously it was getting only 100 apps)
b. Get ad app owner contact email as part of the output

Copy link

ghost commented Jun 12, 2018

Hi,

Could you please share me in PowerShell azure arm module script.

Thanks
Gowrish

@JamesDLD
Copy link

JamesDLD commented Mar 22, 2019

Thank you for this share!
I did just try to run the same with the PowerShell module Az.Accounts 1.3.0 and I observed the following.
Do you have the same ?

  1. Get-AzADApplication doesn't have the switch parameter "-All" anymore
  2. The AzADApplication object doesn't have any more the paramaters "PasswordCredentials" & "KeyCredentials"

image

@JamesDLD
Copy link

Just got my Info, need to use the following !
Get-AzADApplication -ObjectId "xxxxxxxxxxxxxxx" | Get-AzADAppCredential

@JamesDLD
Copy link

All the work remains to you but I re used it to publish a version using Az modules here : https://github.com/JamesDLD/AzureRm-PowerShell/blob/master/Audit-AzAdApplication.ps1
Thank you!

@gdbarron
Copy link

Thanks very much for this code, it gave me a big jump-start in my code. I'd like to make a suggestion to improve performance if you don't mind. I would remove the Get-AzureADApplication calls for .PasswordCredentials and .KeyCredentials as those values are already part of the object from Get-AzureADApplication -All $true. For example, you can replace Get-AzureADApplication -ObjectId $_.ObjectID).PasswordCredentials with $app.PasswordCredentials. You could also send everything through the pipeline instead of appending to a list and you'd probably get a speed boost as well, but only if dealing with many items.

@svarukala
Copy link
Author

Great feedback Greg (@gdbarron). I never realized that $app already has those properties loaded. Definitely will speed up the script. I will update it right away.

@qs1234
Copy link

qs1234 commented Nov 13, 2019

Hello, any chance we can include the Object GUID and Application ID in this script? Thank you so much. It's really helpful!

@svarukala
Copy link
Author

Hello, any chance we can include the Object GUID and Application ID in this script? Thank you so much. It's really helpful!

You can add those two properties as follows:
$results += [PSCustomObject] @{
AppId = $app.ApplicationId;
ObjectId = $app.ObjectId;
CredentialType = "PasswordCredentials"
DisplayName = $app.DisplayName;
ExpiryDate = $.EndDate;
StartDate = $
.StartDate;
KeyID = $_.KeyId;
Type = 'NA';
Usage = 'NA';
Owners = $owner.UserPrincipalName;
}

@svarukala
Copy link
Author

I am working on updating this script to use Az module. But I am seeing some limitations so doing further research.

@svarukala
Copy link
Author

I went ahead and published the Az Module based script here: https://gist.github.com/svarukala/2260c5a3b94208ec348796d5f46e4a5b
The only limitation is, it doesn't capture the Application Owner. We must rely on Azure AD module for that.

@TiloGit
Copy link

TiloGit commented Feb 20, 2020

here for Enterprise Apps with User list (to check who did self registration)
https://gist.github.com/TiloGit/33e95c5afe3acfc959e953db532abc72

@Raka74
Copy link

Raka74 commented Jun 19, 2020

Hello, can someone maybe help me getting only the last x day expiring apps ?

@svarukala
Copy link
Author

Try this cmdlet in shell. This gets expired ones and also those that will expire in 60days. You can change that number.

az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table

@sahitya12
Copy link

Hello everyone can someone help me in power shell script to check comparing the expired date with the current date so we can have a list of all of the expired ones.

@Raka74
Copy link

Raka74 commented Jul 27, 2020

Try this cmdlet in shell. This gets expired ones and also those that will expire in 60days. You can change that number.

az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table

Great! that helps - thank you!

@sahitya12
Copy link

Thank you @Raka74
I have tried using the same script as above with some modifications to get expired app's

$app.PasswordCredentials | where {$.enddate -notlike “” -and $.enddate -LE ((get-date).AddDays(0))} |
%{
$results += [PSCustomObject] @{
CredentialType = "PasswordCredentials"
DisplayName = $app.DisplayName;
EndDate = $_.enddate;

@Karthikchan
Copy link

Try this cmdlet in shell. This gets expired ones and also those that will expire in 60days. You can change that number.

az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table

@svarukala
I get the below error when i run the query you had mentioned
//az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table
az ad sp list: error: argument --query: invalid jmespath_type value: "[?passwordCredentials[0].endDate<='2020-10-20'||keyCredentials[0].endDate<='2020-10-20'].{"
usage: az ad sp list [-h] [--verbose] [--debug] [--only-show-errors]
[--output {json,jsonc,yaml,yamlc,table,tsv,none}]
[--query JMESPATH] [--spn SPN]
[--display-name DISPLAY_NAME] [--filter QUERY_FILTER]
[--show-mine] [--all]
To learn more about [--query JMESPATH] usage in AzureCLI, visit https://aka.ms/CLIQuery//

@svarukala
Copy link
Author

Try this cmdlet in shell. This gets expired ones and also those that will expire in 60days. You can change that number.
az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table

@svarukala
I get the below error when i run the query you had mentioned
//az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'].{"Display Name":appDisplayName,"SP AppId":appId,"Pwd Expiry Date":passwordCredentials[0].endDate, "Key Expiry Date":keyCredentials[0].endDate}" -o table
az ad sp list: error: argument --query: invalid jmespath_type value: "[?passwordCredentials[0].endDate<='2020-10-20'||keyCredentials[0].endDate<='2020-10-20'].{"
usage: az ad sp list [-h] [--verbose] [--debug] [--only-show-errors]
[--output {json,jsonc,yaml,yamlc,table,tsv,none}]
[--query JMESPATH] [--spn SPN]
[--display-name DISPLAY_NAME] [--filter QUERY_FILTER]
[--show-mine] [--all]
To learn more about [--query JMESPATH] usage in AzureCLI, visit https://aka.ms/CLIQuery//

This works in unix shell. Not in PS. To make it work in PS, change the way the dates are created using $(Get-Date).

@sunandha-02
Copy link

@svarukala Is there any method to get the provisioning details via powershell for an application.
Example:
1.When is the last provisioning cycle happened?
2.steady state achieved or not.
3.No.of.errors ocuured during auto provisioning.

@svarukala
Copy link
Author

@svarukala Is there any method to get the provisioning details via powershell for an application.
Example:
1.When is the last provisioning cycle happened?
2.steady state achieved or not.
3.No.of.errors ocuured during auto provisioning.

Can you elaborate what do you mean by last provisioning cycle? Is it the app creation date that you are talking abt?
I am not aware of a 'steady state' property associated with an AAD app.

@gday899
Copy link

gday899 commented Aug 16, 2021

@svarukala Is it possible to also list the Apps that do not have Key/PasswordCredentials? Thanks

@Divyesh85
Copy link

Hi @svarukala i was trying to run this script( only part of the code) and it seems the keycredentials are not getting any value
`# Check service principal expiry dates.

Get-AzureADApplication -All $:true | ForEach-Object {
$name = $.displayname
$BodyTemplate = @"
{
"channel": "$CHANNELNAME",
"username": "SPN is expired",
"text": "$name is Expired $PassCredExpiry.",
"icon_emoji":":crossed_flags:"
}
"@
$BodyTemplate2 = @"
{
"channel": "$CHANNELNAME",
"username": "SPN is Almost expired",
"text": "$name Almost Expired $PassCredExpiry.",
"icon_emoji":":crossed_flags:"
}
"@
$AppID = $
.AppId
$KeyCredExpiry = ($).keycredentials.enddate
$PassCredExpiry = ($
).passwordcredentials.enddate
write-output "Today Date $todaysdate"
write-output "Future Date $futureCHeck"
write-output "Checkign KeyCredExpiry date $KeyCredExpiry and PassCredExpiry $PassCredExpiry"
If($KeyCredExpiry -ne $null)
{
write-output "checking $name"
If ($todaysdate -gt $KeyCredExpiry )
{
write-output "$name has expired at $KeyCredExpiry"
Invoke-RestMethod -uri $SlackChannelUri -Method Post -body $BodyTemplate -ContentType 'application/json'
$json3+= @([PSCustomObject]@{
AppDisplayName = $name;
AppID = $AppID;
CertificateExpireyDate = $KeyCredExpiry;
PasswordExpireyDate = $PassCredExpiry;
Reason = "Expired"
})
} `

when i run this piece i print the values as well with write-output, as you can see but it seems i am not getting any value for this " $KeyCredExpiry = ($_).keycredentials.enddate" any idea why?

@svarukala
Copy link
Author

svarukala commented Oct 27, 2021

In your script I am seeing ($).keycredentials.enddate instead of $_.keycredentials.enddate. The underscore is missing. Could that be the issue?
@Divyesh85. How abt using the script I provided above as is? Is it working in that case?

@svarukala
Copy link
Author

Since Azure AD PowerShell is being deprecated in favor of Microsoft Graph PowerShell SDK, I created a new MS Graph script that is equivalent to this script. You can find it here:
https://pnp.github.io/script-samples/aad-apps-expired-keys/README.html?tabs=graphps

@JQUINONES82
Copy link

//az ad sp list --all

az ad sp list --all --query "[?passwordCredentials[0].endDate<='$(date -d "+60 days" +%Y-%m-%d)'||keyCredentials[0].endDate<='$(date -d "+300 days" +%Y-%m-%d)'].{SP_AppId:appId,PwdExpiryDate:passwordCredentials[0].endDate, Key_Expiry_Date:keyCredentials[0].endDate,Display_Name:displayName,Account_Type: objectType}" -o table

@GuyPaddock
Copy link

GuyPaddock commented May 10, 2023

Another option that leverages the newer Az.Resources module is available here:
https://gist.github.com/GuyPaddock/c3e0fbb1e3724822c77e35a83160af52

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment