Public/Send-ConnectorFile.ps1

<#
.SYNOPSIS
    Uploads a ZIP file to the connected Fortytwo IAM Core connector.

.DESCRIPTION
    Sends a ZIP file to the connector data upload endpoint for the connector selected by Connect-Connector.
    The file is uploaded as multipart/form-data using a form field named "file".

    Before uploading, the cmdlet validates that the path exists, that the target is a file, that the
    file has a .zip extension, and that the ZIP archive can be read completely. Reading every archive
    entry before upload allows the .NET ZIP reader to detect corrupt entries, truncated archives, and
    CRC mismatches before any data is sent to the API.

    This cmdlet requires an active connection established with Connect-Connector. The connector ID is
    taken from the active connection, so it is not specified on this cmdlet.

.PARAMETER Path
    The path to the ZIP file to upload. The path must resolve to an existing file with a .zip extension.
    The ZIP archive is read completely for validation before upload, so large files can take longer to
    process.

.PARAMETER PassThru
    Returns the API response object when the upload succeeds. By default, the cmdlet writes no output
    on success.

.EXAMPLE
    Send-ConnectorFile -Path ".\connector-package.zip"

    Validates and uploads connector-package.zip to the connected connector's data upload endpoint.

.EXAMPLE
    $result = Send-ConnectorFile -Path ".\connector-package.zip" -PassThru

    Validates and uploads connector-package.zip, then stores the API response in $result.

.EXAMPLE
    Get-Item ".\connector-package.zip" | Send-ConnectorFile -Verbose

    Uploads a ZIP file from the pipeline and writes verbose validation and upload progress.
#>

function Send-ConnectorFile {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [ValidateNotNullOrEmpty()]
        [ValidateScript({ Test-Path -LiteralPath $_ -PathType Leaf })]
        [ValidateScript({ [System.IO.Path]::GetExtension($_) -eq ".zip" })]
        [string] $Path
    )

    process {
        if (-not $Script:APIRoot -or -not $Script:AccessTokenProfile) {
            throw "Connector not connected. Please run Connect-Connector first."
        }

        $resolvedPath = Resolve-Path -Path $Path

        Write-Verbose "Validating ZIP file '$resolvedPath' before upload"
        Test-ConnectorZipFile -Path $resolvedPath

        Write-Verbose "Uploading ZIP file '$resolvedPath' to connector data upload endpoint"
        Invoke-RestMethod `
            -Uri "$($Script:APIRoot)data/upload" `
            -Method Post `
            -InFile $path `
            -Headers (Get-EntraIDAccessTokenHeader -Profile $Script:AccessTokenProfile) `
            -SkipHttpErrorCheck `
            -ContentType "application/zip" `
            -StatusCodeVariable statuscode | Out-Null

        if($statuscode -ge 200 -and $statuscode -lt 300) {
            Write-Verbose "File upload successful with status code $statuscode"
        }
        else {
            Write-Warning "File upload failed with status code $statuscode"
        }
    }
}