LearnMicrosoft Teams › 14 · Advanced: automation & APIs

The Teams PowerShell module, properly

One module, two lineages, and automation patterns that either respect its quirks — auth contexts, throttling, the batch machinery — or generate mystery incidents on schedule.

The lineages under one name

MicrosoftTeams bundles Graph-backed cmdlets (Get-Team family — team/ channel/member objects) and the policy/voice engine descended from Skype tooling (Get-Cs* — the ~140 policy types serv365 scans). They differ in error style, paging behaviour and auth nuance; knowing which family a cmdlet belongs to predicts its behaviour (Cs* voice cmdlets are the ones with the long tail of versioned breaking changes — pin module versions, read release notes before upgrading, the admin-surfaces module's rule).

Auth contexts (the operational decision)

  • Interactive (human + MFA): admin work.
  • App-only (certificate + application): unattended automation — the serv365 model: cert in a vault, app registration with least roles, NO stored passwords ever. Coverage note from our own execution audit: the overwhelming majority of Get-* surface works app-only; the exceptions get RECORDED (the honest-gaps discipline), because an automation that silently skips is worse than one that reports 'not served'.

Patterns that survive production

  1. Read-only by construction where possible (the serv365 constitution: Get-* allowlist) — a compromised reporting job should be boring.
  2. Throttling-aware: bulk reads paced with retry-after respect; the module + service WILL throttle store-scale loops.
  3. Batch for writes: New-CsBatchPolicyAssignmentOperation for population-scale policy moves — then READ THE OPERATION RESULT (the assignment-engine module's rule: completion is not success).
  4. Idempotent scripts: desired-state style (check, then set if different) — reruns become safe, and your diffs become meaningful.
  5. Version pinning in CI: the module version is part of the script's contract; upgrades are deliberate events with a changelog read.

What to watch (proofs)

  • Session truth: Get-CsTenant/Get-CsOnlineUser -ResultSize 1 as the connectivity+auth canary at script start — fail fast with a named cause.
  • Throttle encounters: retry-after events in your automation logs — rising counts = pace redesign before the service does it for you.
  • Batch outcomes: operation results persisted per run (serv365's command-execution audit pattern: every cmdlet run, its outcome, stored) — the 'what did the script actually do' answer, forever.
  • Version drift: module version logged per run — the correlation column for 'it broke on Tuesday' (Tuesday's run shows the new version; the release notes show the removed parameter).

PowerShell for this concept

  • Get-CsOnlineUser Returns information about users who have accounts homed on Microsoft Teams or Skype...
  • Get-CsTenant Returns information about the Microsoft Teams or Skype for Business Online tenants...
  • Get-CsUserPolicyAssignment This cmdlet is used to return the policy assignments for a user, both directly...

Discussion

No messages yet — start the thread.

Sign in with your email to join the discussion — we send a one-time link, no password.