Repository navigation
Bounded Pagination in PowerShell Tools for Agents #470
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tridev-tej
wants to merge
1
commit into
PowerShellOrg:main
Choose a base branch
from
tridev-tej:tejesh/powershell-bounded-pagination-blog
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+88
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file added
BIN
+10.1 KB
.../2026/10/bounded-pagination-in-powershell-tools-for-agents/bounded-pagination-example.zip
Binary file not shown.
88 changes: 88 additions & 0 deletions
88
...ent/articles/2026/10/bounded-pagination-in-powershell-tools-for-agents/index.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| --- | ||
| title: "Bounded Pagination in PowerShell Tools for Agents" | ||
| description: "Read a paginated API in PowerShell, limit the requests and records, and tell when you have the full result." | ||
| author: Tejesh Vaish | ||
| authors: | ||
| - Tejesh Vaish | ||
| date: "2026-10-26T04:00:00+04:00" | ||
| categories: | ||
| - PowerShell for Developers | ||
| tags: | ||
| - powershell | ||
| - rest-api | ||
| - ai-agents | ||
| --- | ||
|
|
||
| Say you're pulling inventory into a report. The API has five records, but your first GET brings back just two. The response also includes a `nextToken`, which tells you where to pick up. If your script hands back only the first two records, the caller has no way to tell that three are missing. | ||
|
|
||
| I want the caller to see why the read stopped. Did we get all the records, hit a limit, or run into an error? This example returns that answer alongside the items, so a script or agent can decide whether to use them. | ||
|
|
||
| ## Try it with a local API | ||
|
|
||
| [Download the example files](./bounded-pagination-example.zip) and unzip them. You'll need PowerShell 7.6 and [Node.js](https://nodejs.org/en/download). The example runs locally with built-in Node modules and needs no credentials. | ||
|
|
||
| In a PowerShell terminal, open the extracted `bounded-pagination-example` folder and start the API. | ||
|
|
||
| ```powershell {linenos=false} | ||
| node ./api.mjs | ||
| ``` | ||
|
|
||
| Leave it running. In a second PowerShell terminal, open the same folder. Run the commands below and paste the URL printed by the first terminal when prompted. | ||
|
|
||
| ```powershell {linenos=false} | ||
| $Base = Read-Host 'Paste the base URL printed by api.mjs' | ||
| $page = Invoke-RestMethod -Uri "$Base/normal" -Method Get -NoProxy -ErrorAction Stop | ||
| $page.items | ConvertTo-Json -Depth 20 -Compress | ||
| ``` | ||
|
|
||
| That prints `[{"id":1},{"id":2}]`. Now run the reader against the same API. | ||
|
|
||
| ```powershell {linenos=false} | ||
| & ./Show-Examples.ps1 -Base $Base | ||
| ``` | ||
|
|
||
| The script prints three JSON results in this order. The repeated-token run also writes a separate error message to the terminal. | ||
|
|
||
| | Run | IDs returned | GET attempts | Status | Stop reason | | ||
| | --- | --- | --- | --- | --- | | ||
| | Read all pages | 1, 2, 3, 4, 5 | 3 | `Complete` | `EndOfData` | | ||
| | Stop after two pages | 1, 2, 3, 4 | 2 | `Partial` | `PageBudget` | | ||
| | Try an API that repeats a token | 1, 2 | 2 | `Error` | `RepeatedToken` | | ||
|
|
||
| Use `IsComplete` when you need all five records. Use `StopReason` to find out what happened when the read stopped early. | ||
|
|
||
| ## How the reader decides when to stop | ||
|
|
||
| Page one includes token `A`. The next request sends `A` to get page two. On the normal route, page two gives you `B`, and page three ends the read with `nextToken: null`. An empty page can still point to another page. | ||
|
|
||
| `MaxPages` limits GET attempts, including a failed attempt. `MaxItems` limits how many records you get back. Try asking for three records. | ||
|
|
||
| ```powershell {linenos=false} | ||
| . ./Get-BoundedPage.ps1 | ||
| Get-BoundedPage "$Base/normal" -MaxItems 3 | ConvertTo-Json -Depth 20 | ||
| ``` | ||
|
|
||
| You'll get IDs 1, 2, and 3, with `Partial/ItemBudget`. Page two contains IDs 3 and 4, and only one of them fits. The same rule applies if the reader runs out of room on the last page. If the entire last page fits, the read is complete. | ||
|
|
||
| In the repeat example, page two points back to `A`. The reader has already requested that token, so it stops before another GET. It counts all four records in `ItemsFetched`. Only the two records from page one make it into `ItemsReturned`. | ||
|
|
||
| Open `Get-BoundedPage.ps1` to see the loop in `Invoke-PageStep`. It checks the limits before making a request, validates the whole page, then checks its token before adding records. If a request fails or a response is malformed, the reader returns `Error/ReadFailed` with the records it kept from earlier pages. | ||
|
|
||
| The sample keeps requests on the same local endpoint and turns off redirects and retries. It downloads and decodes the whole page before trimming records, so a single response can still be large. The [operation timeout](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-7.6#-operationtimeoutseconds) covers a stalled read. Set a separate deadline if you need to limit the total time. | ||
|
|
||
| If you keep only part of a page, picking up at the next token would skip the records you left behind. The reader therefore returns no resume token. | ||
|
|
||
| ## Run the checks | ||
|
|
||
| From the second terminal, run the verifier if you want to try empty pages, exact limits, broken responses, and other cases. The verifier starts and stops its own API listeners. | ||
|
|
||
| ```powershell {linenos=false} | ||
| $env:PWSH = (Get-Process -Id $PID).Path | ||
| node ./verify.mjs > ./results.jsonl | ||
| $LASTEXITCODE | ||
| Get-Content -LiteralPath ./results.jsonl -Tail 1 | ||
| ``` | ||
|
|
||
| A passing run exits with code `0` and ends with `{"kind":"summary","cases":65,"passed":true}`. The example ran with PowerShell 7.6.9 and Node.js 26.3.0 on macOS and Ubuntu. Windows verification is still pending. | ||
|
|
||
| When you're done, press Ctrl+C in the first terminal to stop the API. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.