Public/Add-SiteCollectionAppCatalog.ps1

function Add-SiteCollectionAppCatalog {
    <#
    .SYNOPSIS
        Adds a site collection app catalog.

    .DESCRIPTION
        Adds a site collection app catalog to the specified SharePoint
        Online site collection.

        The executing account must have the required permissions to
        administer the SharePoint tenant and the target site collection.

    .PARAMETER TenantUrl
        URL of the SharePoint Online tenant administration site.
        Example: https://contoso-admin.sharepoint.com

    .PARAMETER SiteUrl
        URL of the target SharePoint Online site collection.

    .PARAMETER ClientId
        Client ID of the Entra ID application used for authentication.

    .EXAMPLE
        Add-SiteCollectionAppCatalog `
            -TenantUrl "https://contoso-admin.sharepoint.com" `
            -SiteUrl "https://contoso.sharepoint.com/sites/production" `
            -ClientId "00000000-0000-0000-0000-000000000000"

    .NOTES
        Requires PnP.PowerShell.
    #>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidatePattern('^https://[^/]+-admin\.sharepoint\.com/?$')]
        [string]$TenantUrl,

        [Parameter(Mandatory)]
        [ValidatePattern('^https://')]
        [string]$SiteUrl,

        [Parameter(Mandatory)]
        [ValidateNotNullOrEmpty()]
        [string]$ClientId
    )

    # --------------------------------------------------
    # Connect to SharePoint tenant administration
    # --------------------------------------------------

    try {
        $adminConnection = Connect-PnPOnline `
            -Url $TenantUrl `
            -Interactive `
            -ClientId $ClientId `
            -ReturnConnection `
            -ErrorAction Stop

        Write-Verbose "Connected to SharePoint tenant administration."
    }
    catch {
        throw "Failed to connect to SharePoint tenant administration '$TenantUrl': $($_.Exception.Message)"
    }

    # --------------------------------------------------
    # Connect to the target site collection
    # --------------------------------------------------

    try {
        $siteConnection = Connect-PnPOnline `
            -Url $SiteUrl `
            -Interactive `
            -ClientId $ClientId `
            -ReturnConnection `
            -ErrorAction Stop

        Write-Verbose "Connected to target site collection '$SiteUrl'."
    }
    catch {
        throw "Failed to connect to target site collection '$SiteUrl': $($_.Exception.Message)"
    }

    # --------------------------------------------------
    # Validate site collection administrator permissions
    # --------------------------------------------------

    try {
        $web = Get-PnPWeb `
            -Includes CurrentUser `
            -Connection $siteConnection `
            -ErrorAction Stop

        if (-not $web.CurrentUser.IsSiteAdmin) {
            throw "The authenticated account must be a site collection administrator on '$SiteUrl'."
        }
    }
    catch {
        throw "Failed to validate site collection administrator permissions: $($_.Exception.Message)"
    }

    # --------------------------------------------------
    # Add site collection app catalog
    # --------------------------------------------------

    try {
        Add-PnPSiteCollectionAppCatalog `
            -Site $SiteUrl `
            -Connection $adminConnection `
            -ErrorAction Stop

        Write-Host "Site collection app catalog successfully added to '$SiteUrl'."
    }
    catch {
        throw "Failed to add the site collection app catalog to '$SiteUrl': $($_.Exception.Message)"
    }
}