Sunday, February 9, 2020

Migrating SfB Enterprise Voice Configs to MS Teams

I'm flyyyyyyiiiing through the cloud.....get it? Cloud? Teams is in the cloud. Got it? Good.

The UCDialplans.com Winter of Code continues at a torrid pace!

Hot on the heels of the MS Teams EV Backup/Restore scripts is another script that I can't believe someone hasn't already cooked up.

Say that you have a well-oiled Skype for Business Enterprise Voice deployment that you carefully cultivated over the years into a perfectly tuned beast. You're considering migrating to Teams, but aren't terribly enthusiastic about having to recreate all that magic in Teams.

Well, worry no more! I've created a script that will copy all of your Skype for Business Enterprise Voice settings into MS Teams. It will handle the following:
  • SfB dialplans into Teams dialplans (along with all normalization rules, of course)
  • SfB PSTN usages into Teams PSTN usages
  • SfB voice routes into Teams voice routes
  • SfB voice policies into Teams voice routing policies
  • SfB trunk translation rules into Teams translation rules
  • SfB PSTN gateways into Teams PSTN gateways
Most of this is completely automatic, except for the PSTN gateway part. Teams PSTN gateways have to be publicly accessible via FQDN, and that FQDN's domain name has to be registered in the O365 tenant. Chances are pretty good that the SfB PSTN gateways won't conform to those requirements. The script will first look for an existing Teams gateway that matches each SfB gateway. If one isn't found, the user will be prompted to do one of the following:
  • match the SfB gateway to an existing Teams gateway with a different FQDN
  • create a new Teams gateway with the same FQDN as the SfB gateway (only works if the SfB gateway already meets the Teams FQDN requirements)
  • create an entirely new Teams gateway
  • don't match the SfB gateway
All this is presented to the user in a straightforward menu. Once all the selections are complete, the selected matches are shown before erasing any existing Teams EV configs and migrating the SfB EV configuration:

The usual trained monkeys will then migrate all the SfB EV settings to Teams, with a few caveats:
  • Since Teams doesn't have "sites", site-level SfB dialplans will be converted to user-level dialplans
  • Same deal with site-level voice policies
  • If there are duplicate translation rules, they will be merged into one, but translation rules with the same name, but different patterns/translations will be changed to include the PSTN gateway name to avoid conflicts.
If all goes well, the script should progress like this:

If you want to see more details around how the secret sauce is made, run the script with the -Verbose switch:


Once complete, your SfB Enterprise Voice config should be completely migrated to Teams. Check things over to be sure. If you elected to create Teams PSTN gateways, you will have to revisit them using Set-CsOnlinePSTNGateway to make sure they're configured correctly. 

Hopefully, this script will help make your transition to Teams that much simpler!

To get the script, go on over to my Github page to get the latest version. If you experience any issues, you can create an bug report through there.

https://github.com/kenlasko/SfBEV2TeamsEV


Tuesday, February 4, 2020

Backing up and restoring Teams Enterprise Voice configs

In the cloud....get it?

Whenever I made changes to a Skype for Business Enterprise Voice configuration, either via a UCDialplans.com script or manually, I got into the habit of making a backup of the Enterprise Voice configuration. Skype for Business made this easy with an option directly in the UI that allowed you to backup and, more importantly, restore. I've made use of both options on more occasions than I can think of.

In the MS Teams world, there are a few scripts out there that help you backup your Teams Enterprise Voice configuration as part of a larger backup of the entire environment. However, I haven't found one that will let you restore that backup. Now there is!

I've published two PowerShell scripts that allow you to backup and then restore an MS Teams Enterprise Voice configuration in a few minutes. Slide on over to my Github page for the latest version.

https://github.com/kenlasko/BackupRestoreTeamsEV



BackupRestoreTeamsEV

PowerShell scripts that allow you to easily backup and restore your Microsoft Teams Enterprise Voice configuration

Getting Started

Download the scripts onto your local Windows machine where you normally connect to your MS Teams tenant.

Prerequisites

Requires that you have the Office 365 PowerShell module installed, and that you have a Microsoft Teams Enterprise Voice configuration that you are interested in backing up/restoring. You may have to set your execution policy to unrestricted to run this script:
Set-ExecutionPolicy Unrestricted

Running a backup

Simply run .\Backup-TeamsEV.ps1 from a PowerShell prompt. If you are not already connected to your Teams tenant, the script will prompt for authentication. If your admin account is not a @tenantname.onmicrosoft.com account, then you should use the -OverrideAdminDomain switch.

Restoring a backup

Run .\Restore-TeamsEV.ps1 with the path to the backup file to restore. If you are not already connected to your Teams tenant, the script will prompt for authentication. If your admin account is not a @tenantname.onmicrosoft.com account, then you should use the -OverrideAdminDomain switch.
By default, the script will clean out any existing config, including dialplans, voice routes, voice routing policies, PSTN usages and translation rules. You can override this behaviour by using the -KeepExisting switch.

Monday, February 3, 2020

Undocumented behaviour with dialplans on MS Teams

Who am I talking to? Eartha Kitt? Sorry, wrong number. I was trying to call my car.
I've been spending a lot of time recently messing around with MS Teams dialplans thanks to the recent release of SBC-specific translation rules. For the most part, the overall structure is the same as with Skype for Business on-prem. Some PowerShell commands are different, but most of what you already know is usable in Teams.

The biggest issue with Teams is that there hasn't been a UI for managing your Teams Enterprise Voice layout. This can be an issue if you are big into Direct Routing.  Thankfully, Microsoft recently made available what is hopefully the first round of UI enhancements to the Teams Admin Center. You can now create and manage dialplans in the UI. Microsoft has dutifully updated their documentation to help people navigate these new features.

However, there are some undocumented features that open up some interesting scenarios. Along with these are some extremely frustrating bugs that you should be aware of.

The Hidden Feature

In Skype for Business on-prem, there is a global dialplan that applies to users when there isn't an appropriate site or user-level dialplan. In the Teams documentation, the tenant Global dialplan serves a similar purpose, but there are additional features outside of what can be done on-prem. 

In Teams, Microsoft has published a series of very simple pre-defined dialplans called service country dialplans that apply to nearly every country in the world. You can see these by running Get-CsDialPlan and Get-CsVoiceNormalizationRule. They do the bare minimum, and don't do any real validation. These dialplans cannot be modified. 

The documentation goes on to say that you can define normalization rules in the tenant global dialplan or any number of tenant user dialplans. If a user tenant dialplan isn't assigned to a user, they will be assigned an effective dialplan of whatever is in the tenant global dialplan and the default service country dialplan for that user. Similarly, if a user is assigned to a tenant user dialplan, their effective dialplan will consist of the contents of the assigned tenant user dialplan along with the user's service country dialplan. The tenant dialplans have higher priority than the service country ones. 

The hidden feature is that if you have defined any normalization rules in the tenant global dialplan, those normalization rules will appear at the top of the list of any new tenant user dialplans created afterwards. This can be very useful in large organizations with many sites, but have a common set of extension dial rules. You simply have to define the rules once in the tenant global dialplan, and they will show up in every new tenant user dialplan created from that point forward. This applies to dialplans created in both PowerShell and the Teams Admin Center.

Unfortunately, there isn't a real link between the tenant global and tenant user dialplans. They are simply copies of the original. If you make a change to the tenant global dialplan, it won't be reflected in all your other dialplans. As with Skype for Business, you're still stuck with using PowerShell to manage bulk changes. Overall, it might make deploying new dialplans just a little bit simpler if you choose to take advantage of this undocumented feature.

The Bugs

Unfortunately, there are also a number of annoying bugs/oversights with the new UI. Some are cosmetic, but some will force you to re-create your dialplan if you accidentally encounter one.

Description Discrepancies

If you've used UCDialplans.com to create your dialplans, you may have noticed that I make extensive use of the Description field to let people know where the rules came along with a copyright notice. I even put in linebreaks to make it readable in the SfB Control Panel UI. These descriptions are rather lengthy and go well beyond 255 characters (sorry, not sorry).

Here are my grievances with the Description field in the MAIN dialplan UI:
  1. The Teams admin center dialplan UI doesn't respect the linebreaks and just renders a wall of text.
  2. The UI throws an error that you can only have up to 255 characters, when PowerShell allows a much higher number.
  3. The UI also throws errors about "invalid characters", such as !@#$%^*()=/\[]{}:;?<>+' Again, PowerShell has no issue with any of these characters.



What makes this even more odd, is that the UI for the individual normalization rules exhibits NONE of these issues. It renders the linebreaks properly, and doesn't complain when the description is longer than 255 characters and includes "special" characters.

The External Dialing Prefix Bug

This is a big bug, and am quite surprised it made it through QA. For a bit of background, you can configure Teams so that users can dial an external access prefix (like 9), before dialing an external number. For users coming from a legacy PBX, this is undoubtedly a boon and doesn't force them to retrain years of muscle memory. It also makes off-hook dialing more reliable. For an extended explanation of this feature, go waaay back to one of my posts from 2011 on the topic. I haven't tested it myself, but the details should still apply to Teams.

Most customers don't bother with this feature, and have been happily creating dialplans in Teams/Skype for Business Online for years via PowerShell without defining an external dialing prefix. However, if you create a new dialplan or edit an existing one in the UI, you will not be able to save your changes unless you set an external dialing prefix.

Also, this seems to have found itself into the PowerShell commands themselves, but not completely. You can create a new dialplan with New-CsTenantDialplan without an external dialing prefix, and you can make changes to an existing dialplan with Set-CsTenantDialplan, but if you try to remove an external dialing prefix via PowerShell by setting it to either $NULL or "", you will be denied.

As long as you don't set a prefix, you should be fine. Don't do what I did and set a prefix in the UI to see what happens, and expect to be able to remove it in PowerShell. This forced me to redo my entire dialplan from scratch. Thankfully, UCDialplans.com took care of that in a minute.

Spelling Mistakes

A minor quibble, but one that will force me to keep a close eye on (boo hoo me). The New/Get/Set-CsOnlinePSTNGateway command has options for setting inbound and outbound translation rules:

  • InboundPstnNumberTranslationRules
  • InboundTeamsNumberTranslationRules
  • OutboundPstnNumberTranslationRules
  • OutbundTeamsNumberTranslationRules

Do you see the problem?

Someone's spellcheck didn't work.

Conclusion


I'm trying to get this in front of the right people at Microsoft to get them to fix. Hopefully, this half of my post will have a limited shelf life. Have any of you experienced any of these issues or come across any others? Let me know in the comments.