Get-ExpiringSPN.ps1
function Get-ExpiringSPN { [CmdletBinding()] param ( [Parameter(Mandatory = $true)]$TimeFrameInDays, [switch]$expiry, [switch]$InvalidExpiry ) # Enter the Timefram in Days for the Usage # $TimeFrameInDays = 30 ################################################################ ## Signature $t = @' Package designed and managed by ___ _ _ ___ _ / __| |___ _ _ __| | / __| ___ _ ___ _(_)__ ___ ___ | (__| / _ \ || / _ | \__ \/ -_) '_\ V / / _/ -_|_-< \___|_\___/\_,_\__,_| |___/\___|_| \_/|_\__\___/__/ Powershell package designed to perform IAM housekeeping task for App Registration SP Objects. Contact- Azure Cloud Servives Product Owner. '@ Write-Verbose "$($t)" ################################################################ # Authentication part Write-Verbose 'Checking ManagedIdentity Authentication to platform.' try { Connect-AzAccount -Identity } catch { Write-Warning "Not enough autherization to 'Managed Identity' for performing operations." } #Build a Dateformat for the Filter $TimeFrameDate = Get-Date -Format yyyy-MM-dd ((Get-Date).AddDays(-$TimeFrameInDays)) $azContext = Get-AzContext $token = Get-AzAccessToken -ResourceTypeName MSGraph $authHeader = @{ 'Content-Type' = 'application/json' 'Authorization' = 'Bearer ' + $token.Token } # Fetching all the App registrations $appRegistrations = Get-AzADApplication if (!$appRegistrations) { Write-Warning 'Identity dosenot have AAD Directory RealAll permission. Get permission for the identity you are running cmdlet with.' } else { if ($expiry -or $InvalidExpiry) { $ArrayExpiry = @() $ArrayInvalidExpiry = @() foreach ($appRegistration in $appRegistrations) { Write-Verbose '-----------------------------------' Write-Verbose "Running for $($appRegistration.DisplayName)" $restUri = "https://graph.microsoft.com/v1.0/myorganization/applications/$($appRegistration.Id)" $response = Invoke-RestMethod $restUri -Method 'GET' -Headers $authHeader $allSecrets = ($response.passwordCredentials.displayName -join '; ') $owner = "https://graph.microsoft.com/v1.0/myorganization/applications/$($appRegistration.Id)/owners" $response2 = Invoke-RestMethod $owner -Method 'GET' -Headers $authHeader $owners = ($response2.value.userPrincipalName -join '; ') $ownerName = ($response2.value.displayName -join '; ') # $SignIns = Invoke-RestMethod -Method GET -Uri "https://graph.microsoft.com/v1.0/auditLogs/signIns?`$filter=appid eq '$($appRegistration.appId)' and createdDateTime gt $TimeFrameDate" -Headers $authHeader # $SignIns foreach ($expDate in $response.passwordCredentials.endDateTime) { <# $currentItemName is the current item #> if (($expiry) -and ($expDate -lt (Get-Date).AddDays($TimeFrameInDays)) -and ($expDate -gt (Get-Date))) { <# Action to perform if the condition is true #> $ArrayExpiry += [PSCustomObject]@{ 'AppID' = $appRegistration.id 'AppName' = $appRegistration.displayName 'SecretName' = $allSecrets 'OwnerUPN' = $owners 'OwnerName' = $ownerName 'ExpirationDate' = $expDate # "Usage Count" = ($SignIns.value ).count } # $Array | Select-Object -Property 'AppName', 'SecretName', 'OwnerUPN', 'AppID', 'OwnerName', 'ExpirationDate' | Sort-Object -Property 'Owner Name' -Descending Write-Verbose "$($appRegistration.id) | $($appRegistration.displayName) | $($allSecrets) | $($owners) | $($ownerName) | $($expDate) |" } if (($InvalidExpiry) -and ($expDate -gt (Get-Date).AddDays($TimeFrameInDays))) { <# Action to perform if the condition is true #> $ArrayInvalidExpiry += [PSCustomObject]@{ 'AppID' = $appRegistration.id 'AppName' = $appRegistration.displayName 'SecretName' = $allSecrets 'OwnerUPN' = $owners 'OwnerName' = $ownerName 'InvalidDate' = $expDate # "Usage Count" = ($SignIns.value ).count } # $Array | Select-Object -Property 'AppName', 'SecretName', 'OwnerUPN', 'AppID', 'OwnerName', 'InvalidDate' | Sort-Object -Property 'OwnerName' -Descending Write-Verbose "$($appRegistration.id) | $($appRegistration.displayName) | $($allSecrets) | $($owners) | $($ownerName) | $($expDate) |" } } } try { if ($expiry) { # $Array | Export-Csv -Path 'ExpiringSPNs.csv' -NoTypeInformation Write-Output $ArrayExpiry } elseif ($InvalidExpiry) { # $Array | Export-Csv -Path 'InvalidExpiringSPNs.csv' -NoTypeInformation #used to calculate expiry beyond 2 years or invalid expiries like 2029 Write-Output $ArrayInvalidExpiry } } catch { Write-Error "Exception : Cannot create file in the path $($pwd)" } } else { $t = @' +----------------+----------------------------------------------------------+ | Expiry | E.g : Get-ExpiringSPN -TimeFrameInDays 30 -expiry | +----------------+----------------------------------------------------------+ | InvalidExpiry | E.g : Get-ExpiringSPN -TimeFrameInDays 30 -InvalidExpiry | +----------------+----------------------------------------------------------+ '@ Write-Warning "You must select one of the switch to perform the operation.`n$($t)" } } ################################################################################################ } |