This script will check all registered apps in Azure AD and will return the following information: expiring apps, expired apps, and apps with no expiration date.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# needs permission Application.Read.All,Directory.Read.All
$ClientID = ''
$ClientSecret = ''
$tenant_Id = ''
$TenantName =
$Body = @{
Grant_Type = "client_credentials"
resource = "https://graph.microsoft.com"
client_id = $clientId
client_secret = $clientSecret
}
$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoft.com/$tenant_Id/oauth2/token?api-version=1.0" -Method POST -Body $Body
# Variable Collections #
$path = "C:\temp\"
$today = Get-Date
$Headers = @{
'Content-Type' = "application/json"
'Authorization' = "Bearer $($ConnectGraph.access_token)"
}
$token = $ConnectGraph.access_token
# Force TLS 1.2.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
function Get-GraphData {
param (
[parameter(Mandatory)]
[string]$AccessToken,
[parameter(Mandatory)]
[string]$Uri
)
$Headers = @{
'Authorization' = "Bearer $AccessToken"
}
do {
$Results = Invoke-RestMethod -Uri $Uri -Headers $Headers -ErrorAction Stop
$QueryResults += $Results.value
$Uri = $Results.'@odata.nextLink'
} while ($Uri)
return $QueryResults
}
#This request get application info
$uri = "https://graph.microsoft.com/beta/applications/"
[array]$apps = Get-GraphData -AccessToken $Token -Uri $uri
$credentials = @()
if ($apps) {
foreach ($app in $apps) {
$ApiUrl = "https://graph.microsoft.com/beta/applications/"+$app.id+"/owners"
$owner = Invoke-WebRequest -Method GET -Uri $ApiUrl -ContentType "application/json" -Headers $headers | ConvertFrom-Json
$app.KeyCredentials | foreach-object {
#write-host $_.KeyId $_.DisplayName
$credentials += [PSCustomObject] @{
CredentialType = "KeyCredentials";
DisplayName = $app.DisplayName;
AppId = $app.AppId;
ExpiryDate = $_.EndDateTime;
StartDate = $_.StartDateTime;
#KeyID = $_.KeyId;
Type = $_.Type;
Usage = $_.Usage;
Owners = $owner.value.userPrincipalName;
Expired = (([DateTime]$_.EndDateTime) -lt $today) ? "Yes" : "No";
}
}
$app.PasswordCredentials | foreach-object {
#write-host $_.KeyId $_.DisplayName
$credentials += [PSCustomObject] @{
CredentialType = "PasswordCredentials";
DisplayName = $app.DisplayName;
AppId = $app.AppId;
ExpiryDate = $_.EndDateTime;
StartDate = $_.StartDateTime;
#KeyID = $_.KeyId;
Type = 'NA';
Usage = 'NA';
Owners = $owner.value.userPrincipalName;
Expired = (([DateTime]$_.EndDateTime) -lt $today) ? "Yes" : "No";
}
}
}
}
$credentials | Export-Csv -Path $path\credentials.csv -NoTypeInformation
#$credentials | Format-Table | Out-String|ForEach-Object {Write-Host $_}
CredentialType | DisplayName | AppId | ExpiryDate | StartDate | Type | Usage | Owners | Expired |
---|---|---|---|---|---|---|---|---|
PasswordCredentials | Alit-GraphAPI | d52bda31-bd71-4a17-b563-7921a17d79e7 | 4.7.2023 21:07:35 | 5.4.2023 21:07:35 | NA | NA | bensi@alit.is | No |
KeyCredentials | Portals-alit | ff8c1144-2535-458c-bd1b-79e30beb927e | 2.9.2024 19:06:20 | 5.9.2022 20:45:16 | AsymmetricX509Cert | Verify | bensi@alit.is | No |
reference https://pnp.github.io/script-samples/aad-apps-expired-keys/README.html?tabs=graphps