Dial plans work a bit differently in Skype Online than they do in on-premise deployments. In on-prem deployments, dial plans are completely independent of one another. Users assigned either a specific site or user-level dial plan will only use the normalization rules contained within that dial plan. Normalization rules assigned at the global level do not apply.
In Skype Online, users can be assigned to either a tenant global dial plan or a tenant user dial plan. As with Skype for Business on-prem, users will get normalization rules from the global tenant dial plan, unless they are explicitly assigned to a user tenant dial plan. There is no inheritance from tenant global to tenant user dial plans.
However, users WILL inherit dial plan normalization rules from a Skype Online global dial plan specific to the country where their phone numbers are hosted. This is the default dial plan that all users are assigned to in the absence of a tenant global or user dial plan.
If you were to run Get-CsDialPlan on your tenant, you will see dial plans for most of the countries in the world (220 to be exact. 12 short of what's in the Skype Optimizer, but who's counting?). These dial plans are pretty basic, accounting for national and international dialing prefixes but not much else. The US and UK dial plan normalization rules are shown below:
Name
|
Priority
|
Pattern
|
Translation
|
US Intl Dialing
|
0
|
^011(\d+)$
|
+$1
|
US Long Distance
|
1
|
^1(\d+)$
|
+1$1
|
US Default
|
2
|
^(\d+)$
|
+1$1
|
US Extension Rule
|
3
|
^((\+)?(\d+))(;)?(ext|extn|EXT|EXTN|x|X)(=)?(\d+)$
|
$1;ext=$7
|
GB Intl Dialing
|
0
|
^00(\d+)$
|
+$1
|
GB Long Distance
|
1
|
^0(\d+)$
|
+44$1
|
GB Default
|
2
|
^(\d+)$
|
+44$1
|
GB Extension Rule
|
3
|
^((\+)?(\d+))(;)?(ext|extn|EXT|EXTN|x|X)(=)?(\d+)$
|
$1;ext=$7
|
The rules are quite rudimentary, and don't allow for capturing and fixing user-initiated dialing errors such as overdialing, incorrect adding of national prefixes for international calls, or local calls. The extension rule is quite interesting because it appears to have been written by someone who really doesn't know how to use regular expressions. Unless your extension rule matches the very specific cases of ext, extn, EXT, EXT, x or X, then it won't work. If they used my standard for pattern and translation, it would be both simpler and would capture pretty much ANY style of writing phone numbers with extensions:
Pattern: ^\+?(\d+)\D+(\d+)$If you look at the dial rules for other countries, you'll see the only difference between them is the long distance and international dialing prefix and the country code. I get that it can be tricky to maintain dial rules for 230+ countries, but hey if one simple Canadian dude can do it, couldn't Microsoft???
Translation: +$1;ext=$2
Aaaanyways, the global dial plan for your given country is applied along with any tenant level dial plans. It appears that the tenant dial plans are applied first, followed by the global dial plan for your country.
This means you can use the Skype Optimizer to create more nuanced normalization rules that will work better than the default ones. You can't disable the global dial plan, so if a user dials a number not covered by your tenant dial plans, then the global ones will apply. So, even if someone tries to dial a completely nonsensical number such as 00000023423422348987987998770, it would get captured by the global Default normalization rule and would allow the user to dial that number. Of course, it wouldn't get far, but I would think that if you can prevent users from dialing invalid numbers at the client level, it would keep Skype Online servers from having to use precious system resources to parse that number and notify the user it is invalid.
Thankfully, this means the Skype Optimizer is still relevant in the Skype Online world. You can still use it to create dial plans and normalization rules that will make the user dialing experience better, including support for:
- Overdialing
- Local number dialing patterns
- Extensions
- Removing national prefixes from internationally dialed numbers
- Slices, dices and makes julienne fries
Just select the desired options for your country, press the Generate Rules button, and run the script. It will ask for your credentials for your Skype Online tenant and will then ask if you want to create a tenant global or tenant user dial plan. It will then apply said normalization rules to your tenant. That's all it takes!
Buy now! Operators are standing by!
Hi Ken, loving the optimizer, thank you so much. I've donated and will try to keep at it for each deployment.
ReplyDeleteJust two queries.
1. What would be the best way to define 0 as operator/reception?
2. What amount of time do you normally allow for dial plan to take full effect on clients i.e. dialling iOS Teams app?
Hey Stephen,
DeleteThe best way to define 0 as an operator would be to create an extension rule in UCDialplans. Select the "Single" checkbox, and input the receptionist's phone number under "Main Number Prefix" and 0 under "Extension Start". It will then create a normalization rule that will translate 0 to that user.
Oh, and to your second question, I actually don't know how long it takes for dialplans to fully take effect. In my experience, you have to wait an indeterminate amount of time for nearly ANYTHING to take effect. My attitude is "If something isn't working the way you expect, wait some more".
DeleteHi Ken, Just wanted to get more clarity on supported regex methods in Skype and teams.
ReplyDeleteAre the named group regex supported
I've never tried using that method in SfB or Teams.
DeleteHi Ken, is there a script to assign VoiceRoutePolicy and Numbers to 2000 users in one Tenancy. hate to run commnds multiple times:
ReplyDeleteSet-CsUser -Identity "[USERNAME]@[COMPANY].com" -OnPremLineURI tel:+852XXXXXXXX -EnterpriseVoiceEnabled $true -HostedVoiceMail $true
Grant-CsOnlineVoiceRoutingPolicy -Identity "[USERNAME]@[COMPANY].com" -PolicyName "No Restrictions"
Yes, you can definitely do this. You need to put the usernames and LineURIs in a CSV file with the headers "username,phone". Then you import that using:
Delete$UserData = Import-Csv UserList.csv
Then you can simply pipe this to something like:
ForEach ($User in $UserData) {
Set-CsUser -Identity $User.username -OnPremLineURI $User.phone -EnterpriseVoiceEnabled $true -HostedVoiceMail $true
Grant-CsOnlineVoiceRoutingPolicy -Identity $User.Username -PolicyName "No Restrictions"
}