What it does
The outbound routing chain for Direct Routing: a voice routing policy holds an ordered list of PSTN usages, each usage holds voice routes, and each route pairs a regex number pattern with a set of SBCs. Dial plans sit in front of it, normalising what the user typed into E.164 before routing runs.
Key facts
- Build order:
Set-CsOnlinePstnUsage -Identity Global -Usage @{Add="UK"}, thenNew-CsOnlineVoiceRoute -NumberPattern ... -OnlinePstnGatewayList ... -Priority n -OnlinePstnUsages "UK", thenNew-CsOnlineVoiceRoutingPolicy -OnlinePstnUsages ..., thenGrant-CsOnlineVoiceRoutingPolicy. - PSTN usages are evaluated in the order they appear in the policy. The first usage with a matching route wins and later usages are never looked at.
- Within a usage, routes are tried by
Priority— lower number first. - SBCs listed in a single route's
OnlinePstnGatewayListare tried in random order, not list order. For ordered failover, use separate routes with different priorities. - Number patterns match the base number only —
;ext=is ignored for matching. - No matching route means the call fails, unless the user also has a Calling Plan, which acts as the final fallback.
- Setting the Global (Org-wide default) voice routing policy hits every voice-enabled user, including Calling Plan and Operator Connect users — whose calls can then go out of your SBC.
- Dial plans: the service country dial plan is Microsoft-managed; tenant dial plans (Global or user-scoped) add normalisation rules on top. Maximum 1,000 tenant dial plans. Cmdlets:
New-CsTenantDialPlan,New-CsVoiceNormalizationRule,Grant-CsTenantDialPlan,Get-CsEffectiveTenantDialPlan,Test-CsEffectiveTenantDialPlan. - Gateway translation rules (
New-CsTeamsTranslationRule) are applied per SBC viaInboundTeamsNumberTranslationRules,InboundPSTNNumberTranslationRules,OutboundTeamsNumberTranslationRulesandOutboundPSTNNumberTranslationRules. Limit 400 rules per tenant. Rules run in the listed order. - Direct Routing numbers can be 3–38 digits. Extensions use
;ext=with 1–12 digits.
When to use / skip
Every Direct Routing tenant needs at least one policy, usage and route. What varies is how far you go. A single-country estate with one SBC pair can live happily on one usage with a catch-all ^\+44 route and a couple of priority tiers. Multi-country estates, least-cost routing, or regulatory splits (some countries forbid toll bypass) are where the usage ordering earns its keep.
Dial plans are optional for most UK deployments now — users dial E.164 or national format and the service country plan handles it. You need a tenant dial plan for short extension dialling, access codes, or a client who insists on "9 for an outside line". Don't build dial plans to fix carrier formatting — that's what gateway translation rules are for.
Configuration decisions
- Leave the Global voice routing policy empty and assign named policies, or populate Global? In mixed tenants (any Calling Plan or Operator Connect users) leave it empty.
- Usage granularity: per-country, per-call-class (national, mobile, international, premium), or per-site. Call classes let you build restriction tiers by assembling usages into policies.
- Route priorities for failover between SBCs or regions — remember randomisation within a route.
- Where to translate numbers: tenant dial plan (user-facing, also affects call history and click-to-dial) vs gateway translation rules (per trunk, invisible to the user) vs the SBC itself.
- Whether premium-rate and international are blocked in Teams routing or at the carrier. Do both if fraud exposure matters.
- Group policy assignment vs direct user assignment for voice routing and dial plans.
Gotchas
- A greedy pattern in an early usage swallows everything.
^\+in the first usage means your international-restricted users can dial anywhere. - Changing usage order needs
Set-CsOnlineVoiceRoutingPolicy -OnlinePstnUsages @{Replace=...}with the full list — an Add appends to the end. - Two SBCs in one route is load-sharing, not primary/backup. People design it as primary/backup and then wonder why half the calls go to the DR site.
- The ingress-SBC exception: if the call came in via an SBC that's also a valid egress for the route, that SBC is preferred regardless of priority. Watch this in forwarding and simultaneous ring.
- Emergency dial strings for Direct Routing no longer arrive with a
+from Teams clients. Route patterns that assume^\+999miss them — see the emergency calling doc. - Normalisation rules apply to call history and links, so a sloppy rule shows up as broken redial, not just broken dialling.
Consultant notes
- Write the regex in a design table with test numbers for each route, then prove them with
Test-CsEffectiveTenantDialPlanand the Direct Routing diagnostic. - Anchor every pattern with
^and$. Unanchored patterns match more than you think. - Keep naming boring and consistent:
UK-National,UK-Mobile,INTL. The person who inherits it will thank you. - Script the whole lot. Rebuilding routing by hand in the admin center across a dozen sites is how typos get into production.
Revisit if Microsoft changes route-level SBC selection or how Teams clients format emergency dial strings