function/microsoft365/Switch-AzureADApplicationAccess.ps1

Function Switch-AzureADApplicationAccess {
    <#
        .SYNOPSIS
        Renew or Reset certificate
 
        .DESCRIPTION
        Renew or Replace certificate based access to azure ad.
 
        .PARAMETER Name
        Name for Certificate and AzureADApplicationKeyCredential
 
        .PARAMETER CertLifetime
        Lifetime for the new Certificate
 
        .PARAMETER KeyExportPolicy
        Export Policy for the Certificate
 
        .PARAMETER CertEndDate
        Lifetime of the expiring Certificate. The certificates that are older than this date, will be renewed.
 
        .PARAMETER ApplicationName
        Name of Application to reset all certificate based access
 
        .OUTPUTS
        System.Object[]
 
        .EXAMPLE
        Switch-AzureADApplicationAccess -Name "renewed_cert" -CertEnddate (Get-Date).AddDays(60) -CertLifetime (Get-Date).AddYears(1)
 
        .LINK
        https://github.com/gisp497/psgisp
    #>

    [CmdletBinding(DefaultParametersetName='lifetime')]
    param (
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            HelpMessage = "Name for Certificate and AzureADApplicationKeyCredential",
            ParameterSetName='resetcertificate'
        )]
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            HelpMessage = "Name for Certificate and AzureADApplicationKeyCredential",
            ParameterSetName='lifetime'
        )]
        $Name,

        [Parameter(
            Mandatory = $False,
            HelpMessage = "Lifetime for the new Certificate",
            ParameterSetName='resetcertificate'
        )]
        [Parameter(
            Mandatory = $False,
            HelpMessage = "Lifetime for the new Certificate",
            ParameterSetName='lifetime'
        )]
        [datetime]$CertLifetime = (Get-Date).AddYears(1),

        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            HelpMessage = 'Export Policy for the Certificate',
            ParameterSetName='resetcertificate'
        )]
        [Parameter(
            Mandatory = $false,
            ValueFromPipeline = $true,
            HelpMessage = 'Export Policy for the Certificate',
            ParameterSetName='lifetime'
        )]
        [ValidateSet('Exportable', 'ExportableEncrypted', 'NonExportable')]
        [string]$KeyExportPolicy = 'Exportable',

        [Parameter(
            Mandatory = $False,
            HelpMessage = "Lifetime of the expiring Certificate",
            ParameterSetName='lifetime'
        )]
        [datetime]$CertEndDate = (Get-Date).AddDays(60),

        [Parameter(
            Mandatory = $True,
            HelpMessage = "Name of Application to reset all certificate based access",
            ParameterSetName='resetcertificate'
        )]
        $ApplicationName
    )
    Begin {
        #check if there is a connection to azure ad
        try {
            $null = Get-AzureADTenantDetail -ErrorAction Stop
        }catch{
            Throw "You need to connect to Azure AD to use this function."
        }

        #create output array
        $OutputArray = @()
    }
    Process {
        #create loop for all azure ad applications
        Get-AzureADApplication | Select-Object DisplayName,ObjectId,KeyCredentials,PasswordCredentials | ForEach-Object {
            $AzureADApplication = $_

            switch ($PSCmdlet.ParameterSetName) {
                lifetime {
                    #loop for every azure ad key credentials (certificate)
                    $AzureADApplication.KeyCredentials | Where-Object {$CertEnddate -gt $_.Enddate} | ForEach-Object {
                        #create new certificate and keycredentials
                        $NewCertificate = New-AzureADApplicationCertificate -Name $Name -ObjectId $AzureADApplication.ObjectId -KeyExportPolicy $KeyExportPolicy -CertLifeTime $CertLifetime

                        #add value to object
                        $OutputObject = New-Object -TypeName psobject
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Type' -Value 'Certificate'
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Thumbprint' -Value $NewCertificate.Thumbprint
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Application' -Value $AzureADApplication.DisplayName

                        #Add Object to Array
                        $OutputArray += $OutputObject
                    }

                    #loop for every azure ad password credentials (client secret)
                    $AzureADApplication.PasswordCredentials | Where-Object {$CertEnddate -gt $_.Enddate} | ForEach-Object {
                        #create new client secrets
                        $ClientSecret = New-AzureADApplicationPasswordCredential -ObjectId $AzureADApplication.ObjectId -EndDate $CertLifetime

                        #add value to object
                        $OutputObject = New-Object -TypeName psobject
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Type' -Value 'ClientSecret'
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'ClientSecret' -Value $ClientSecret.Value
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Application' -Value $AzureADApplication.DisplayName

                        #Add Object to Array
                        $OutputArray += $OutputObject
                    }
                }
                resetcertificate {
                    if ($AzureADApplication.DisplayName -eq $ApplicationName) {
                        #create new certificate and keycredentials
                        $NewCertificate = New-AzureADApplicationCertificate -Name $Name -ObjectId $AzureADApplication.ObjectId -KeyExportPolicy $KeyExportPolicy -CertLifeTime $CertLifetime

                        #add value to object
                        $OutputObject = New-Object -TypeName psobject
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Type' -Value 'Certificate'
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Thumbprint' -Value $NewCertificate.Thumbprint
                        Add-Member -InputObject $OutputObject -MemberType NoteProperty -Name 'Application' -Value $AzureADApplication.DisplayName

                        #Add Object to Array
                        $OutputArray += $OutputObject

                        #delete client secrets if exist
                        try {
                            $AzureADApplication.PasswordCredentials | ForEach-Object {Remove-AzureADApplicationPasswordCredential -ObjectId $AzureADApplication.ObjectId -KeyId $_.KeyId -ErrorAction Stop}
                        }
                        catch {
                            Throw "Can't delete old client secrets ($TenantId): $_"
                        }

                        #delete all other certificates
                        try {
                            $AzureADApplication.KeyCredentials | Where-Object {$_.Keyid -ne $NewCertificate.KeyId} | ForEach-Object {Remove-AzureADApplicationKeyCredential -ObjectId $AzureADApplication.ObjectId -KeyId $_.KeyId -ErrorAction Stop}
                        }
                        catch {
                            Throw "Can't delete old certificate ($TenantId): $_"
                        }
                    }
                }
            }
        }
    }
    End {
        #return object
        Return $OutputArray
    }
}