Find available phone numbers with Get-TeamsNumbers.ps1

I believe assigning phone numbers in Microsoft Teams can waste hours for an organization with multiple ranges and locations. What if you could run a PowerShell routine to find the next available number in a number range and at the same time know how many numbers you have left?😱 Now you can, with Get-TeamsNumbers.ps1. Watch my full session from Commsverse21 at the bottom of this post where I demo this script routine.

Fun fact: This script is based on my very popular phone number management routine I crated for Skype for Business Server 2015 called Get-SfBNumbers.ps1.

Disclaimer: This tool is provided as is and you are free to re-use the routines found in the script for your own use, but should not be incorporated in commercial products without author’s consent. If you got any feedback on the script let me know on Twitter.

Get started

  • Download the script from GithHub.
  • I prefer to open it in PowerShell ISE.
  • Add your number ranges and numbers in retention.
Figure 1: Add your ranges and numbers you want to reserve. If the script give and Int32 error on the range, I have experienced that the formatting of the above code can be wrong, try typing it manually instead of copying it
  • Before you run the script, make sure you Connect-MicrosoftTeams with the latest version.
    • You need to be either Teams Communications Administrator, Teams Administrator or Global Admin to run the script.
    • The numbers cannot be discovered via GraphAPI, only via the Teams PowerShell module.
  • Save the script and run it directly in PowerShell ISE.
    • Use examples to see how it can be run as normal ps1 script.
    • I prefer to run it in ISE because then you can play with the $Reports variable which I will show you later.
  • Keep in mind that it may run for a while if you have thousands of users.
  • Already after first run, you should get some good results as shown below.
    • The routine works for number used through Calling Plans, Operator Connect and Direct Routing.
Figure 2: Notice that there are 42 numbers in retention, these are classified as Gold and Silver numbers. You can add your own numbers in retention as well. You see total numbers available which is useful in order to know that you have enough numbers.

What it does

  • Uses Get-CsOnlineUser to fetch all users and accounts with a populated LineURI.
    • This includes Auto Attendands, Call Queues, Meeting Rooms, Common Area Phones and all other objects with a phone number.
  • Creates a complete overview of all numbers and number ranges.
    • Exports to csv C:\_Report\PhoneNumbers<Date>.csv so that you can import it to Excel.
    • Prints a GridView so that you can do a direct sort and search.
    • Prints the summary of all ranges to console.
    • What the script does can be controlled in the parameters section at the top of the script.
Figure 3: All settings can be specified in the parameter section

Find all available numbers for a range

The advantage of running the script in ISE is that you get access to all the variables the script uses. A very useful variable is the $Report variable. Notice that all number ranges has an Identity and has and attribute called AllAvailableNumbers. You can use these to get all numbers and then start assigning them in bulk to users. In Figure 2 we see the number range has Identity set to 2 which we can use like this:

Figure 4: Getting all available numbers as an array which again can be used for bulk assignment

Automatic retention of numbers

There might be numbers you don’t want to give to normal users, but you want to reserve for Auto Attendants, Call Queues or VIP users. The script automatically classifies Gold and Silver numbers based on regex. I have not created this regex myself, it is based on the script routine Paul Valiant provided for me back in 2015. It still works well :) My slide from my talk at Microsoft Ignite 2015 is still valid, when explaining Gold and Silver numbers.

Figure 5: Examples for Gold, Silver, Bronze and cultural numbers you should consider not to assign to users.

You can reserve your own numbers at the top section of the script, and notice that you can add your own comment and it wont be offered as the next number

Figure 6: The comment will also show in your csv export and GridView output.

Attend my session at Commsverse to learn more

I am speaking at Commsverse 15-16th of September 2021 about phone number management. In that session I will explain this script routine, but go even further and show how it can be used in automation and how to troubleshoot phone numbers for users and explain why country code is key for Microsoft Teams Phone System. Read more here.

Watch my full session from Commsverse21 where I demo this script routine

Managing phone numbers for users when using Direct Routing, the new Operator connect or event through Calling Plans? MVP Ståle Hansen got you covered. Learn his routine for automating numbers, identifying Gold, Silver and Bronze numbers and even reserving single numbers for re-use.

What you will learn
– How to automate finding available numbers for new users
– How to reserve numbers for future use
– Assign and troubleshoot phone numbers for users.

2 thoughts on “Find available phone numbers with Get-TeamsNumbers.ps1

  1. Hi there,

    Not sure if you are aware – this is a great script – but with later versions of the Teams PS module it throws an error:

    Microsoft.Teams.ConfigAPI.Cmdlets.internal\Search-CsUser : Filter couldn’t be parsed
    At C:\Program Files\WindowsPowerShell\Modules\MicrosoftTeams\3.1.1\net472\custom\PsExt\Get-CsUserSearch.ps1:52 char:13
    + Microsoft.Teams.ConfigAPI.Cmdlets.internal\Search-CsUser …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: ({ PageSize = , …olicy = False }:f__AnonymousType74`9) [Search-CsUser_Search], Exception
    + FullyQualifiedErrorId : BadArgument,Microsoft.Teams.ConfigAPI.Cmdlets.Generated.Cmdlets.SearchCsUser_Search
    Determining what range to work with… Done!
    Finding all numbers in ranges… Done!
    Generating complete internal database of used and available numbers…Cannot index into a null array.
    At C:\TeamsDDIs\Get-TeamsNumbersManchester.ps1:601 char:17
    + … if ($number.NumberInRange -eq $FunctionAllUSed[$Count].did){
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

    I can’t quite work out where the issue actually is, but as MS seem intent on knobbling get/set cs-user, I would bet related to that?

    • Found the issue, the current Teams #PowerShell module fails on Get-CsOnlineUser -Filter {LineURI -ne $Null}. Changed to Get-CsOnlineUser | Where-Object {$_.LineUri -ne $Null} Verified OK. Thanks for letting me know. Download the latest version of the script to get the update👍

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.