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 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.


  1. This is truly a masterpiece ..!
    The amount of work this saves is stupendous!
    Well done

  2. Fantastic, thanks so much!

  3. Hi Ken,

    This is great work does this script work with Lync 2013 as well.

  4. It should work just fine. Please let me know if it throws any errors.

  5. Hi Ken, quick question. Love the script. It could save us tons of manual labour. Now, if I do not have the connecting gateways (yet) would I be able to run this and add the connecting gateways later, but get all the other information copied from our exiting SfB configuration?

    1. Yes, you can add the gateways later, but you'll have to add any translation rules manually.

  6. Trying to run this script and i'm able to connect to tenant successfully, but then it comes back with this error.

    PS C:\Support> .\SFB2TeamsEnterprisevoice.ps1
    Getting Skype for Business Enterprise Voice details
    Get-CsDialPlan: C:\Support\SFB2TeamsEnterprisevoice.ps1:58
    Line |
    58 | $Dialplans = Get-CsDialplan
    | ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    | Run Connect-MicrosoftTeams before running cmdlets.

    1. Yes, you'll have to run Connect-MicrosoftTeams beforehand. The script hasn't been updated to use the new PowerShell Teams module yet.

    2. You also have to run this on a system that has the on-prem SfB PS module installed. Looking closer at the error, its happening at the part where its trying to get your SfB details.

    3. Appreciate the feedback. I ran this directly on the SFB server. It does actually work to an extent. If I do the command prior it still attempts to authenticate during the script and the errors with message. If I don't do the connect-microsoftteams it prompts for authentication and then errors at same part. Do you think -verbose may provide further details?

    4. I wanted to follow up on this. I decided to read the fine print in the Skype for Business Online Connector to the Teams powershell module article. I was not grasping that I would actually have to modify your script. Once I made the changes everything worked as expected. Simply had to adjust the new-csonlinesession command to connect-microsoftteams.

      A Little snippet from Microsoft article:
      When using Teams PowerShell Module 2.0 or later, update your scripts that refers New-CsOnlineSession to Connect-MicrosoftTeams. Import-PsSession is no longer required to establish a Skype for Business Online Remote PowerShell Session as that is done implicit when using Connect-MicrosoftTeams.

    5. I wanted to follow up on this. I was not grasping at the fact I would have to modify the existing script and swap out the command new-csonlinesession with connect-microsoftteams. Once I did this and ran command everything worked as expected. Thanks again for the script. This was really helpful. Hopefully someone else will benefit from my oversight.

      a little snippet from Microsoft article:
      When using Teams PowerShell Module 2.0 or later, update your scripts that refers New-CsOnlineSession to Connect-MicrosoftTeams. Import-PsSession is no longer required to establish a Skype for Business Online Remote PowerShell Session as that is done implicit when using Connect-MicrosoftTeams.

  7. Hi Ken, as always a great Script however I did not that my SfB\Lync implementions have always used multiple PSTN usages for fail over routing (as detailed excellently by you here ; however in Teams the same does not apply and secondary PSTN usages that are the same are never utilised as you need multiple voice routes within the same usage instead. As such when I tried this in one of my tenants failover would then not occur as Teams would not hit the other PSTN usage with the other SBC.

    1. Wow! I don't see many comments coming through that aren't spam anymore. I'm curious about this. Historically, routes within PSTN usages would be utilized somewhat randomly and couldn't be counted on for true failover. I wonder if this has changed. Also, are you absolutely positive that multiple PSTN usages doesn't work? That would be a pretty major change.

    2. Hi Ken, it does seem to have changed then per here in Example 2 there is a note;

      "The order of PSTN usages in voice routing policies is critical. The usages are applied in order, and if a match is found in the first usage, then other usages are never evaluated"

      As with Skype I would have had two PSTN usages for say emergency with routes multiple SBC's but this is clearly now a non-starter with teams and its definately a case of a single PSTN usage with multiple routes under it.

    3. That's the way its always been. What it should say is that if a match is found AND THE ROUTE IS AVAILABLE, then it won't evaluate further.