CogniSkill · Microsoft Graph with PowerShell
Content review copy. This does not replace the site theme. For SC-300, this preview shows additions; the existing teaching is retained on import.
What you will make
Build a paginated Graph-style report that detects loops and keeps a failed collection separate from a complete empty result.
What you need
PowerShell objects; tenant access required only for optional live extension.
Use PowerShell 7. This script simulates two Graph-shaped pages. It deliberately does not import the Graph module or call Microsoft services.
How to work through it
- Understand the mechanism and predict the result.
- Run or trace the fixture and preserve the evidence.
- Change the inputs, expose a failure and explain the repair.
- Complete a project and answer the retrieval questions.
Scope
A focused practical workshop, not a complete beginner-to-expert programme. Allow time for the exercises and project; the pace depends on your prior experience. Related CogniSkill books are optional next steps. No purchase is required.
Applied capability and learning route
Design complete, least-privilege directory reporting with pagination and retry controls.
Follow the lessons in order: establish the model, trace the supplied evidence, attempt the case, compare the worked solution, and complete the changed-condition project. The target is intermediate reasoning within this stated scope, not mastery of the entire profession or product. If a prerequisite is unfamiliar, pause and use the linked foundational teaching before attempting the project.
All teaching, explained answers and core synthetic practice are free. Some operational labs require separately available software, a licensed test tenant or an authorized lab; offline completion does not claim hands-on product proficiency.
How to complete this course
Study the worked examples, attempt the exercises before opening solutions, and submit your own project notes. Completion records are self-reported; practical competence requires the stated verification.
An endpoint contract comes before a module command
Your practical task
Build a paginated Graph-style report that detects loops and keeps a failed collection separate from a complete empty result.
You need a user inventory, not permission to change accounts. First shape a supplied sample object locally; then design the optional Graph access. The core exercise requires no tenant and stores no tokens.
How the system works
An API page is not the whole dataset. A next-link indicates more data, and its full URL is part of the service’s paging contract. Treating the first page as complete can produce a convincing but incomplete access or inventory report. In this offline lab the page URLs are keys in a fixture, so you can practise traversal without a tenant or access token.
Pagination also needs a termination rule. If a next-link repeats, a naïve loop can run forever. The HashSet records visited page keys and stops when a key appears twice. That is a collection failure, not permission to return whatever happened to be collected before the loop. Production code should preserve a partial result only when the report explicitly marks it incomplete.
Read-only permissions still need least privilege and approved use. The permission required depends on the endpoint, delegated or application context, and the properties you request. A working sample is not proof that broad directory permissions are necessary. For a live extension, select the exact documented endpoint, review its permission table and token context, and avoid placing tokens in logs or exported CSV files.
An endpoint contract comes before a module command
For a Microsoft Graph request, identify resource path, operation, access mode, required permission and expected response shape. Installing the SDK does not grant authorization. Delegated and application access are different contexts; a user sign-in in a browser is not evidence for an unattended collector.
This course's fixture simulates Graph-shaped pages. It deliberately avoids tenant access, credentials and consent. Use it to learn control flow and failure handling before adapting a collector to a documented endpoint. Record collection scope so a later report does not treat a filtered result as an organization-wide inventory.
Reasoning model
An API report is complete only when every required page has been retrieved successfully under a known filter and permission scope. A successful first response is not a complete inventory. Follow the service-provided continuation mechanism rather than reconstructing offsets. A retry loop needs bounds and must distinguish transient throttling from persistent authorization failure. Record completion state so a partial report cannot masquerade as an empty or final inventory.
Official reference for further study
Follow the chain without redefining completeness
Prepare the lab
Use PowerShell 7. This script simulates two Graph-shaped pages. It deliberately does not import the Graph module or call Microsoft services.
$ErrorActionPreference = 'Stop'
$pages = @{
'page-1' = @{value=@([pscustomobject]@{id='1';displayName='Ana'});'@odata.nextLink'='page-2'}
'page-2' = @{value=@([pscustomobject]@{id='2';displayName='Ben'});'@odata.nextLink'=$null}
}
function Read-FixturePages {
param([hashtable]$Pages,[string]$First)
$seen = [System.Collections.Generic.HashSet[string]]::new()
$url = $First
$items = [System.Collections.Generic.List[object]]::new()
while ($url) {
if (-not $seen.Add($url)) { throw 'Repeated page link' }
if (-not $Pages.ContainsKey($url)) { throw 'Missing page response' }
$page = $Pages[$url]
foreach ($item in $page.value) { $items.Add($item) }
$url = $page['@odata.nextLink']
}
return $items.ToArray()
}
$result = @(Read-FixturePages -Pages $pages -First 'page-1')
$result | Select-Object id,displayName | Format-Table
if (($result.id -join ',') -ne '1,2') { throw 'Pagination test failed' }
Work through the evidence
Draw the page chain
Write page-1 → page-2 → end before execution. Count records separately from pages: two pages could contain zero, two, or hundreds of records. A page count is not a user count.
Test an empty complete result
Set page-1 value to an empty array and its next-link to null. The function should return no items without claiming that collection failed. Then remove page-1 from the fixture and verify that missing response fails explicitly.
Inject a loop
Set page-2 next-link to page-1. The function must throw Repeated page link. Explain why silently treating a repeated URL as end-of-data could conceal a broken provider or collector.
Expected baseline result
Baseline output contains IDs 1 and 2. Missing page and loop fixtures fail explicitly. A complete empty fixture returns zero records with a completed collection status, not a fabricated success after an error.
Follow the chain without redefining completeness
Microsoft Graph can return an @odata.nextLink for another page. A page's HTTP success is not the same as a complete collection. In the offline fixture, page-1 yields Ana and points to page-2, which yields Ben and terminates. The expected population is two records.
Now make the second page empty but retain a valid subsequent link to a third page. Empty page content is not a universal end condition; the pagination contract determines continuation. For a real adapter, use supported next links, preserve required headers, bound work and validate destinations before forwarding credentials. Provider paging behavior varies by endpoint.
Evidence laboratory — attempt before reading the solution
A mocked directory API returns page 1 with users U1,U2 and next link N2. The first N2 request returns 429 with Retry-After 3 seconds; the approved test harness then returns U3,U4 and next link N3. N3 returns U5 and no continuation. A faulty script stops after page 1 and labels its output “all users.” Trace the correct sequence, expected unique-user count and the completion flag. All responses here are fixtures; no live tenant call is required.
Official reference for further study
Exercise: a failed middle page
Change the evidence
Separate live permissions
For a possible users report, locate the endpoint’s current permissions and supported properties in official documentation. Distinguish delegated access, where a signed-in user’s context is involved, from application access. Do not guess a broader scope to make a failed request succeed.
Plan rate-limit handling
A 429 is not an empty page. A live collector should honour the service’s retry guidance, bound the retries, and mark a run failed when the retry budget is exhausted. Retrying every error identically may repeat authorization failures indefinitely.
Specify the report boundary
Add a collected-at timestamp, record count, page count, requested properties and completeness flag. A reviewer should be able to see whether the result came from a complete collection rather than infer completeness from a polished CSV.
Diagnose failures
The report always contains the first hundred records
Check whether the collector follows next-links rather than assuming one response is complete. A service page limit is not the size of the tenant.
The collector gets forbidden and returns no users
Authorization failure is not an empty directory. Preserve the error and review endpoint permission, token context and consent.
Retrying creates an infinite run
Use bounded retries and a page-loop guard. The recovery rule must terminate and report failure when it cannot satisfy the collection contract.
A second worked example
# Local sample: no connection required
$users = @([pscustomobject]@{
DisplayName='Ana Example'; UserPrincipalName='ana@example.test'
})
$users | Select-Object DisplayName, UserPrincipalName
# Optional live pattern: after approved SDK install and permission review
# Connect-MgGraph -Scopes 'User.ReadBasic.All'
# Get-MgUser -All -Property DisplayName,UserPrincipalName |
# Select-Object DisplayName,UserPrincipalName
# Disconnect-MgGraph
The local section proves projection of sample properties, not live permissions. The commented pattern shows the relationship between sign-in, retrieval and output. Verify current consent and endpoint requirements before running it in an authorized tenant. -All requests all pages supported by that cmdlet; selecting fields also limits what you retain in the report.
Transfer exercise
A report has exactly one page of users. What evidence should you inspect before concluding that this is the entire directory?
Worked transfer answer
Inspect paging behavior, applied filters, permission scope and any errors. Compare the intended population with an approved independent count. A successful first page is not proof of completeness. Never log access tokens to debug the mismatch.
Exercise: a failed middle page
The first page contains 100 users and the second request receives a throttling response with a Retry-After value. The report deadline is sooner than the required wait. What should the collector publish?
Worked reasoning
It must not label the first page a complete inventory. Respect supported retry guidance within the job budget or stop/defer with a partial/incomplete status and clear provenance. Retrying faster because the deadline is inconvenient can worsen throttling. A downstream absence report should refuse incomplete collection rather than classify every missing user as deleted.
Worked laboratory solution
Compare your reasoning with the worked solution
The successful sequence collects U1,U2, waits/retries according to the mocked throttling contract and bounded policy, collects U3,U4, then U5, and marks complete only after the terminal page. Expected unique users are five. The intermediate count of two is partial, not an authoritative total. Do not treat every error as retryable: an authorization failure needs permission/context diagnosis. If retries exhaust, retain collected data with an explicit incomplete/error status rather than quietly publishing it as complete.
Official reference for further study
Workbook already downloaded
Collector acceptance tests
Build your project
Add page count and completeness metadata to the fixture collector. Test an empty successful result, two pages, a missing second page and a repeated next-link. Write a separate live-integration plan naming endpoint, permission model, retry limit and export fields; do not add real credentials.
What a complete result looks like
Pagination completeness is explicit
The two offline pages produce IDs 1 and 2 exactly once. Test a valid empty page, a missing collection property and a repeated next link separately. The live-design appendix records the supported endpoint permission, token audience, next-link handling, bounded retry policy and secret redaction. The offline run establishes pagination behavior only; it does not establish that a Microsoft tenant granted the required permission.
Acceptance criteria
- Local and live steps distinguished
- Permissions justified
- Pagination checked
- No tokens retained
Self-review record
Record your inputs, expected and actual outputs, failing test, correction, and remaining limitation. A reviewer should be able to reproduce your conclusion from your evidence. Compare your result with the lab baseline; explain any deliberate extension rather than simply copying its output.
Retrieval practice
Answer in your own words before opening each explanation. Use an example from the fixture to justify your answer.
Why follow a next-link?
Compare your reasoning
It identifies the next page in the response contract; the first page may be incomplete.
Is a forbidden response equivalent to zero users?
Compare your reasoning
No. It is failed authorization and tells you nothing about the count of users.
Why test offline fixtures first?
Compare your reasoning
They make pagination, empty results and failure handling reproducible before permissions and network variability are introduced.
Collector acceptance tests
Exercise a normal chain, terminal empty result, missing page, repeated link, malformed item and bounded-retry exhaustion. Define a stable identity and reject contradictory duplicates under your chosen contract. Distinguish “collected zero items completely” from “collected nothing because authentication failed.”
Deliver the scope, endpoint/version plan, permission justification, sanitized error references and collection status. A production adapter also needs secret handling and redirect/destination review. The learner project remains offline unless an explicitly authorized tenant lab is separately arranged; no live Graph execution is claimed by these fixtures.
Transfer project — changed conditions
Implement a mock page-fetch function and test normal pagination, a repeated next link, retry exhaustion and a duplicated user across pages. Decide whether the report needs unique identities or raw records and document your deduplication key. Add a permission review showing the exact read operation and the least-privilege documented authorization for the chosen mode. Keep secrets and raw tokens out of logs.
Practical assessment rubric
Score each dimension 0–2: 0 = absent or materially incorrect; 1 = partly correct with an unresolved gap; 2 = correct, explicit and supported by the supplied evidence or an actual labeled lab result.
- Evidence/model: identify the relevant entities, inputs, assumptions and boundaries without inventing facts.
- Main result: derive the case-specific expected result, calculation or decision and show the intermediate reasoning.
- Failure/boundary: test the changed condition and explain why the original conclusion does or does not transfer.
- Verification: supply reproducible steps and expected/observed results; label manual traces as manual, not executed.
- Communication/safety: explain limitations, owners and a proportionate next action without unsafe or unnecessary access.
Target: at least 8/10, with no zero in main result or communication/safety. This is a local learning rubric, not an accredited certification standard. A written/manual solution demonstrates reasoning only; operational competence additionally requires the relevant executable lab in an authorized environment. The native multiple-choice score is separate and does not automatically grade this rubric.
Submission template
- My input/evidence and assumptions:
- Expected result with calculations or trace:
- My implementation/decision and justification:
- Changed-condition result:
- Observed execution, or explicitly labeled manual trace:
- Failure and recovery evidence:
- Unverified limitation and next action:
- Self-score with evidence for each dimension:
Remediation
If the main result is wrong, reconstruct the supplied case from the raw inputs before changing code or controls. If the boundary case is wrong, identify the assumption that changed and rerun both the original and changed case. If verification is missing, do not convert a prediction into an observed result. Reattempt the transfer task without copying the worked solution, then explain it to another person.
Official reference for further study
Assessment: explain your decisions
Choose an answer and write your reason before opening each explanation. Then explain why the other choices do not fit the evidence. Use missed questions to revisit the lesson. This knowledge check is only one part of assessment: complete the practical transfer project as well. It does not predict certification-exam success.
1. Which permission direction fits basic inventory?
- Documented minimum read access
- Directory-wide write by default
- A copied admin token
Answer and explanation
Documented minimum read access — Read requirements should be matched to minimum permissions.
2. Does one successful response establish complete inventory?
- Always
- No; pagination and scope matter
- Only if formatted
Answer and explanation
No; pagination and scope matter — API paging can limit the returned set.
3. Which should be excluded from debug logs?
- Row count
- Error category
- Raw access token
Answer and explanation
Raw access token — Raw tokens are credentials.
4. A Graph-shaped page is empty but has a supported nextLink. Is collection necessarily complete?
- No; follow the paging contract
- Yes, empty always means end
- Yes, if the first request succeeded
Answer and explanation
No; follow the paging contract — The continuation contract, not the page’s row count alone, determines completion. Endpoint-specific behavior must be respected.
5. A required Retry-After exceeds this job’s budget. What should it do?
- Publish the first page as the entire directory
- Defer or report incomplete rather than retry too early or claim completeness
- Ignore the delay
Answer and explanation
Defer or report incomplete rather than retry too early or claim completeness — Respect throttling and collection limits. A truncated population must not become a false complete inventory.
6. The next page repeats a previously visited link. What should the fixture do?
- Silently declare completion
- Repeat forever until the service changes
- Stop with an explicit loop error
Answer and explanation
Stop with an explicit loop error — A repeat is a failed pagination contract in this fixture. Neither infinite work nor fabricated completeness is appropriate.
7. When can the fixture report be labeled complete?
- After N3 succeeds and supplies no continuation.
- After the first HTTP success.
- As soon as two users are displayed.
Answer and explanation
After N3 succeeds and supplies no continuation. — Completion depends on traversing the entire continuation chain, not merely receiving a successful page.
8. What is the expected unique-user count?
- Four because throttling discards page 2.
- Five.
- Two.
Answer and explanation
Five. — After the bounded retry succeeds, all three pages contribute U1 through U5.
9. Retries exhaust at N2. What should the report say?
- All users: two.
- No users exist.
- Partial/incomplete with the error and collected rows clearly identified.
Answer and explanation
Partial/incomplete with the error and collected rows clearly identified. — An interrupted inventory cannot support either a complete count or a claim of absence.
Use the explained questions above for offline practice. A scored attempt requires the course assessment on CogniSkill.ca.
Optional deeper study
If you want a longer learning path, inspect the related CogniSkill SC-300 books in the existing book panel. Choose by the book’s actual scope and edition. The exercises, downloads and answers in this course are complete without purchase.