Private/Invoke-KB4PagedRequest.ps1

function Invoke-KB4PagedRequest
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string] $Path,

        [Parameter()]
        [hashtable] $Query = @{},

        [Parameter()]
        [switch] $All,

        [Parameter()]
        [ValidateRange(1, 500)]
        [int] $PageSize = 100,

        [Parameter()]
        [ValidateRange(1, [int]::MaxValue)]
        [int] $Page,

        [Parameter()]
        [string] $Cursor,

        [Parameter()]
        [switch] $UsePagePagination,

        [Parameter()]
        [switch] $Raw
    )

    $requestQuery = @{} + $Query
    # KnowBe4 defaults to 100 and caps page size at 500.
    $requestQuery['per_page'] = $PageSize

    if ($PSBoundParameters.ContainsKey('Page'))
    {
        $requestQuery['page'] = $Page
    }

    if (-not [string]::IsNullOrWhiteSpace($Cursor))
    {
        $requestQuery['cursor'] = $Cursor
    }

    if (-not $All)
    {
        # Single-page calls still unwrap data unless the caller requested Raw.
        return Get-KB4ResponseBody -Response (Invoke-KB4Request -Path $Path -Query $requestQuery) -Raw:$Raw
    }

    if ($Raw)
    {
        $responses = [System.Collections.Generic.List[object]]::new()
    }
    else
    {
        $results = [System.Collections.Generic.List[object]]::new()
    }

    if ($UsePagePagination)
    {
        $pageNumber = if ($PSBoundParameters.ContainsKey('Page'))
        {
            $Page
        }
        else
        {
            1
        }

        do
        {
            $requestQuery['page'] = $pageNumber
            $response = Invoke-KB4Request -Path $Path -Query $requestQuery

            if ($Raw)
            {
                $responses.Add($response)
            }
            else
            {
                foreach ($item in @(Get-KB4ResponseData -Body $response.Body))
                {
                    $results.Add($item)
                }
            }

            $count = Get-KB4ResultCount -InputObject (Get-KB4ResponseData -Body $response.Body)
            # Page pagination ends when the API returns fewer items than requested.
            $pageNumber++
        }
        while ($count -eq $PageSize)

        if ($Raw)
        {
            return $responses
        }

        return $results
    }

    $nextCursor = if ([string]::IsNullOrWhiteSpace($Cursor))
    {
        'true'
    }
    else
    {
        $Cursor
    }

    do
    {
        $requestQuery['cursor'] = $nextCursor
        $response = Invoke-KB4Request -Path $Path -Query $requestQuery

        if ($Raw)
        {
            $responses.Add($response)
        }
        else
        {
            foreach ($item in @(Get-KB4ResponseData -Body $response.Body))
            {
                $results.Add($item)
            }
        }

        # Cursor pagination ends when no next cursor can be found.
        $nextCursor = Get-KB4NextCursor -Response $response
    }
    while (-not [string]::IsNullOrWhiteSpace($nextCursor))

    if ($Raw)
    {
        return $responses
    }

    $results
}