Private/Invoke-DuneApiRequest.ps1

function Invoke-DuneApiRequest {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory)]
        [string]$Uri,

        [Parameter()]
        [ValidateSet("GET", "POST", "PATCH", "DELETE", "PUT")]
        [string]$Method = 'GET',

        [Parameter()]
        [switch]$ExtractItems, # enables paging and extract items / will not return StatusCode

        [Parameter()]
        $Body

        # [Parameter(ParameterSetName='WebSession')]
        # [Microsoft.PowerShell.Commands.WebRequestSession]$WebSession,

        # [Parameter(ParameterSetName='Token')]
        # $Token,

        # [Parameter()]
        # [switch]$SkipAuth
    )

    begin {
        Write-Debug "$($MyInvocation.MyCommand)|begin"
        Assert-DuneSession
        $Url = $("{0}/{1}" -f $DuneSession.DuneApiUrl, $Uri)
        # $AuthUrl = "{0}{1}" -f $DuneSession.DuneApiUrl, "/auth/credentials"
        # if (-not ($SkipAuth) -and ($DuneSession.Type -eq 'Credential' -and -not $DuneSession.AuthSession -or ($DuneSession.AuthSession.Cookies.GetCookies($AuthUrl)).Expired -contains $True <#-or $DuneSession.SessionUrl -ne $ENV:SB_API_URL -or $DuneSessionUser -ne $ENV:SB_API_USER -or $DuneSessionPass -ne $ENV:SB_API_PASS -or $DuneSessionTenant -ne $ENV:SB_TENANT#>)) {
        # Invoke-DuneApiAuth
        # }
        $Headers = @{
            "X-Tenant"     = $DuneSession.Tenant
            "Accept"       = "application/json"
            "Content-Type" = "application/json"
        }
        if ($DuneSession.Type -eq 'SocialLogin') {
            # Convert SecureString to plain text in a way compatible with PowerShell 5.
            if ($DuneSession.Token -is [System.Security.SecureString]) {
                $PlainToken = $null
                $convertCmd = Get-Command ConvertFrom-SecureString -ErrorAction SilentlyContinue
                if ($convertCmd -and $convertCmd.Parameters.Keys -contains 'AsPlainText') {
                    $PlainToken = $DuneSession.Token | ConvertFrom-SecureString -AsPlainText
                }
                else {
                    $bstr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($DuneSession.Token)
                    try { $PlainToken = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr) }
                    finally { if ($bstr) { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr) } }
                }
            }
            else {
                $PlainToken = $DuneSession.Token
            }
            $Headers.Authorization = "Bearer $PlainToken"
        }
    }

    process {
        $PagingUrl = $Url

        $ResultObjects = @()
        do {

            $WebRequest = @{
                Uri             = $PagingUrl
                Method          = $Method
                Headers         = $Headers
                UseBasicParsing = $true
            }
            if ($DuneSession.Type -eq 'Credential') { $WebRequest.WebSession = $DuneSession.AuthSession }

            If ($DebugPreference -ne 'Continue') { $WebRequest.Verbose = $false }
            If ($Body) {
                $WebRequest.Body = $($Body | ConvertTo-Json -Compress -Depth 16)
            }
            Write-Debug "$($MyInvocation.MyCommand)|process|WebRequest: $($WebRequest | ConvertTo-Json -Depth 16 -Compress)"
            try {
                $Response = Invoke-WebRequest @WebRequest
                if ($Response.StatusCode -notlike "2??") {
                    Write-Error ("{0} {1} returned statuscode: {2} ({3})" -f $Method, $Uri, $Response.StatusCode, $Response.StatusDescription) -ErrorAction Stop
                }
                if ($ExtractItems) {
                    $Results = $Response.Content | ConvertFrom-Json
                    if (($Results | Get-Member).Name -contains 'total' -and ($Results | Get-Member).Name -contains 'items') {
                        $Total = $Results.total
                        $Results = $Results.Items
                    }
                    $ResultObjects += $Results
                    if ($Total -and ($ResultObjects.Count -ne $Total)) {
                        Write-Debug ("$($MyInvocation.MyCommand)|process|Use paging for {0} {1}. (CurrentReturnedItems {2} / TotalReturnItems {3})" -f $Method, $Uri, $ResultObjects.Count, $Total)
                        $PagingUrl = $PagingUrl | Add-UriQueryParam "skip=$($ResultObjects.Count)"
                    }
                }
                else {
                    return $Response
                }
            }
            catch {
                if ($_.Exception.Message) {
                    if ($_.ErrorDetails.Message) {
                        try {
                            $ErrorDetailsMessage = $_.ErrorDetails.Message | ConvertFrom-Json
                            Write-Error ("{0} {1} returned error: {2} ({3})" -f $Method, $Uri, $_.Exception.Message, $ErrorDetailsMessage.responseStatus.message)
                        }
                        catch {
                            $ErrorDetailsMessage = $_.ErrorDetails.Message
                            Write-Error ("{0} {1} returned error: {2} ({3})" -f $Method, $Uri, $_.Exception.Message, $ErrorDetailsMessage)
                        }
                    }
                    else {
                        Write-Error ("{0} {1} returned error: {2}" -f $Method, $Uri, $_.Exception.Message)
                    }
                }
            }
        } until ((-not $ExtractItems) -or (-not $Total) -or ($ResultObjects.Count -eq $Total))
        return $ResultObjects
    }

    end {
        Write-Debug "$($MyInvocation.MyCommand)|end"
    }
}