LearnMicrosoft Teams › 5 · Calling & Enterprise Voice

Dial plans and voice routing: the resolution chain

Between digits typed and a trunk chosen sits a five-stage pipeline: normalise, authorise, match usage, pick route, try gateways. Every 'this number won't dial' lives at exactly one stage — learn to name which.

The flow — what actually happens

Plain-language first; the packet-level view underneath each step is what you'd see in a Wireshark trace, and what healthy looks like.

  1. Normalisation (dial plan)

    Whatever the user typed — 0207..., x4021, 9-1-... — the dial plan's regex rules rewrite it to E.164 (+442079460958). Tenant dial plans layer onto Microsoft's per-country service plan; first matching rule wins.

    On the wire Test without calling: Get-CsEffectiveTenantDialPlan piped to Test-CsEffectiveTenantDialPlan -DialedNumber — shows the matched rule and output. THE tool for stage-1 disputes.
  2. Authorisation (calling policies)

    May this user make this class of call at all? TeamsCallingPolicy (calling on/off), dial-out restrictions, outbound blocked-number patterns org-wide. A block here fails fast and looks like a routing error but is policy.

    On the wire The user's effective policies: Get-CsUserPolicyAssignment. Org blocklist: Get-CsTenantBlockedCallingNumbers (in the nightly scan).
  3. Usage matching (for Direct Routing users)

    The normalised number walks the user's OnlineVoiceRoutingPolicy: an ordered list of PSTN USAGES (think 'call classes': UK-National, International). The number pattern decides which usage claims the call.

    On the wire Get-CsOnlineVoiceRoutingPolicy for the user's policy; its OnlinePstnUsages list is the search order.
  4. Route selection

    Within the matched usage, ROUTES (regex + gateway list + priority) compete; highest-priority matching route wins and offers its SBC list.

    On the wire Get-CsOnlineVoiceRoute sorted by priority — the actual competition table. A number matching NO route in any listed usage = the instant-fail 'call failed' class.
  5. Gateway attempts

    Teams offers the call to the route's SBCs (respecting OPTIONS health from the DR contract); an SBC that rejects or times out passes the call down the list, then to the next route. Only when everything is exhausted does the user hear failure.

    On the wire SBC SIP logs show the INVITE with the final normalised number — if the INVITE never arrives, the call died in stages 1-4 inside Microsoft; if it arrives and fails, the SBC/carrier leg owns it. This one observation halves every DR investigation.

Design rules that keep the chain sane

  • Normalise everything to E.164 at stage 1 — routes and usages then only ever deal in one format; extension dialling handled by explicit rules, not exceptions downstream.
  • Name usages by call class, routes by destination+priority (UK-National, route-uk-nat-primary-sbc1) — the config reads as intent.
  • Order usages from specific to broad in every policy — Emergency and Premium usage placement errors are how premium-rate fraud escapes.
  • Fewer, well-tested dial plan rules beat exhaustive ones: each rule is a regex someone must maintain; test with the actual weird inputs your users type.

What to watch (proofs)

  • Stage 1: Test-CsEffectiveTenantDialPlan -DialedNumber <input> -Identity <user> — matched rule + translated output; screenshot = dispute over.
  • Stage 2: Get-CsTenantBlockedCallingNumbers + user's TeamsCallingPolicy (both in serv365's scan — the blocklist changing is a drift event you'll see).
  • Stages 3-4 for one user in one view: Get-CsOnlineVoiceRoutingPolicy + Get-CsOnlinePstnUsage + Get-CsOnlineVoiceRoute — build the user's personal routing table on one page; the number that matches nothing is stage-4's proof.
  • Stage 5: SBC INVITE logs + TAC per-SBC health — arrived-and-failed vs never-arrived.
  • End to end: PSTN usage report per call shows the number AS ROUTED (post- normalisation) — compare to what the user typed for stage-1 evidence in the wild.

PowerShell for this concept

Discussion

No messages yet — start the thread.

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