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

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.

  1. Evidence/model: identify the relevant entities, inputs, assumptions and boundaries without inventing facts.
  2. Main result: derive the case-specific expected result, calculation or decision and show the intermediate reasoning.
  3. Failure/boundary: test the changed condition and explain why the original conclusion does or does not transfer.
  4. Verification: supply reproducible steps and expected/observed results; label manual traces as manual, not executed.
  5. 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

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?

  1. Documented minimum read access
  2. Directory-wide write by default
  3. 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?

  1. Always
  2. No; pagination and scope matter
  3. 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?

  1. Row count
  2. Error category
  3. 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?

  1. No; follow the paging contract
  2. Yes, empty always means end
  3. 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?

  1. Publish the first page as the entire directory
  2. Defer or report incomplete rather than retry too early or claim completeness
  3. 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?

  1. Silently declare completion
  2. Repeat forever until the service changes
  3. 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?

  1. After N3 succeeds and supplies no continuation.
  2. After the first HTTP success.
  3. 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?

  1. Four because throttling discards page 2.
  2. Five.
  3. 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?

  1. All users: two.
  2. No users exist.
  3. 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.