Get-ExpiringSPN.ps1

function Get-ExpiringSPN {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]$TimeFrameInDays,
        [switch]$Expiry,
        [switch]$Expired,
        [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 "`n$($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
    if ($token = Get-AzAccessToken -ResourceTypeName MSGraph -erroraction SilentlyContinue) {
        Write-Host "Authorization using MSGraph"    } else {
        $token = Get-AzAccessToken -ResourceUrl "https://graph.microsoft.com"
        Write-Host "Authorization using GraphURI"   }
    $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 ReadAll permission. Get permission for the identity you are running cmdlet with.'
    }
    else {
        if ($Expiry -or $InvalidExpiry -or $Expired) {
            $ArrayExpiry = @()
            $ArrayInvalidExpiry = @()
            $ArrayExpired = @()
            foreach ($appRegistration in $appRegistrations) {
                Write-Verbose '-----------------------------------'
                $appRegName = $($appRegistration.DisplayName)
                Write-Verbose "Running for $($appRegName)"
                if ($appRegistration.Id) {
                    $appRegistrationId = $appRegistration.Id
                } else {
                    $appRegistrationId = $appRegistration.ObjectId
                }
                $restUri = "https://graph.microsoft.com/v1.0/myorganization/applications/$($appRegistrationId)"
                $response = Invoke-RestMethod $restUri -Method 'GET' -Headers $authHeader
                $allSecrets = ($response.passwordCredentials.displayName -join '; ')
                $owner = "https://graph.microsoft.com/v1.0/myorganization/applications/$($appRegistrationId)/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) {
                    if (($expiry) -and ($expDate -lt (Get-Date).AddDays($TimeFrameInDays)) -and ($expDate -gt (Get-Date))) {
                        $ArrayExpiry += [PSCustomObject]@{
                            'AppID'          = $appRegistrationId
                            '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 "$($appRegistrationId) | $($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'       = $appRegistrationId
                            '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 "$($appRegistrationId) | $($appRegistration.displayName) | $($allSecrets) | $($owners) | $($ownerName) | $($expDate) |"
                    }
                    # Expired in past X-Days
                    if (($Expired) -and ($expDate -gt (Get-Date).AddDays(-$TimeFrameInDays)) -and ($expDate -lt (Get-Date))) {
                        $ArrayExpired += [PSCustomObject]@{
                            'AppID'       = $appRegistrationId
                            'AppName'     = $appRegistration.displayName
                            'SecretName'  = $allSecrets
                            'OwnerUPN'    = $owners
                            'OwnerName'   = $ownerName
                            'ExpiredDate' = $expDate
                            # "Usage Count" = ($SignIns.value ).count
                        }
                        # $Array | Select-Object -Property 'AppName', 'SecretName', 'OwnerUPN', 'AppID', 'OwnerName', 'InvalidDate' | Sort-Object -Property 'OwnerName' -Descending
                        Write-Verbose "$($appRegistrationId) | $($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
                }
                elseif ($Expired) {
                    Write-Output $ArrayExpired
                }
            }
            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 |
            +----------------+----------------------------------------------------------+
            | Expired | E.g : Get-ExpiringSPN -TimeFrameInDays 30 -Expired |
            +----------------+----------------------------------------------------------+
'@

            Write-Warning "You must select one of the switch to perform the operation.`n$($t)"
        }
    }
    ################################################################################################
}