SCRIPT: Get-UnusedNumbers.ps1

Script Name: Get-UnusedNumbers.ps1

Script Author: Lync MVP Ståle Hansen

Original Post: https://msunified.net/2013/04/23/lync-20102013-script-to-find-available-numbers-in-a-lync-deployment/

Log:

  • V20 23.04.2013
    • The entire script is a function and is ready to be reused in scripts to enable users for Enteprise Voice
      • The function can take a Unassinged Number Identity and return the value of a new unassigned number
      • If you don’t provide input to the function it will go through all Unassigned Numbers in the deployment
      • It will check if there is no Unassigned Number range defined, and point you to TechNet for how to configure it
    • Support for numbers larger than 10 digits added
      • A problem with the old script was that it did not support numbers with more than 10 digits (Int32)
      • I have rewritten the code to create a list of the number range that supports Int64 values which should be enough digits for phone numbers
    • I recommend working with the numbers in full E.164 format to be able to support numbers with different countrycode length
  • V10 21.04.2011
    • After some great feedback I have updated the script to be much more dynamic by supporting different country codes in the same deployment
    • The only customization (in theory) you have to do in the script is changing the length of your country code
      • This can be done in line 019
    • Added check if Unassigned Numbers are in E.164 format, if its not, continue to the next number serie
  • V06 12.04.2011
    • Added finding common area phones with line uri, thanks to colleague Jarle Utne
  • v05 01.04.2011
    • Added finding numbers for users enabled with private lines, thanks again to Paul-Christiaan Diks
    • Added line $used=$used | ForEach-Object {$_.ToLower()} to convert the $used array to all lower case letters, because the {$_.Replace(“tel:+47”, “”) would not work on uppercase letters
    • Added finding numbers for analog devices, thanks to Marjus Sirvinsks for the tip
  • v04 24.03.2011
  • v03 22.02.2011
    • Added supression of error messages when removing “tel:+47” from arrays. Got errors if they where empty
  • v02 09.02.2011
    • Added TrustedApplicationEndpoint filter as well
  • v01 17.01.2011
    • Initial Script
    • Gets numbers from users, Exchange UM Contacts and Dial In Conferencing
    • Lists total available numbers, total numbers, and what numbers are available
    • Fixed country code to +47

Doubleclick on the code field, press CTRL+A and CTRL+C to copy the script in to PowerShell ISE which I recommend as my favourite script editor

####################################################################################################
# Get-UnusedNumbers.ps1
#
# v20 April 2013 by Ståle Hansen, Lync MVP (http://msunified.net)
#
# Thanks to the PowerShell community for great guides, articles and forum posts
#
####################################################################################################
[System.Console]::ForegroundColor = [System.ConsoleColor]::White
clear-host

Write-Host "Script for finding unused numbers in Lync Server 2010/2013, by MVP Ståle Hansen"
Write-Host

Function Get-Unused{

    param($Unassigned=$Null)
    if($Unassigned -ne $Null) {$UnassingedRun=(Get-CsUnassignedNumber $Unassigned)}
    elseif($Unassigned -eq $Null){
    	if((Get-CsUnassignedNumber) -eq $Null){
    		Write-Host "You do not have any Unassigned Numbers defined"
		    Write-Host
    		Write-Host "Go to this TechNet article to see how-to:"
		    Write-Host "http://technet.microsoft.com/en-us/library/gg412748.aspx"
		    Write-Host
		    Write-Host "Also see how to configure the announcement service:"
		    Write-Host "http://technet.microsoft.com/en-us/library/gg412783.aspx"
		    Write-Host
		    [System.Console]::ForegroundColor = [System.ConsoleColor]::Gray

    	}
        else {$UnassingedRun=(Get-CsUnassignedNumber)}
    }

    foreach ($Serie in ($UnassingedRun)) {

    #The CountryCodeLength is the length of you countrycode. I recommend to leave it at zero and list the numbers as fully E.164 format.
    #If you want to remove more than 2 digits, change the $CountryCodeLength
    $CountryCodeLength=0
    #The "tel:+" string is the +5 lenght that is added in the next line
    $CountryCodeLength=$CountryCodeLength+5

    #Now we get the replace string so that all numbers can be converted to an int
    #In the norwegian case this value becomes tel:+47
    $ReplaceValue=($Serie.NumberRangeStart).Substring(0,$CountryCodeLength)

    #Check to see if Unassigned Numbers are in E.164 format, if its not, continue to the next number serie
    if (($ReplaceValue.Substring(0,5)) -ne "tel:+"){
        Write-Host "The script requires that Unassigned Numbers are populated in E.164 format" -Foregroundcolor Yellow
        Write-Host "It appears that the number range " -nonewline
        Write-Host $Serie.Identity -nonewline -Foregroundcolor Green
        Write-Host " is not in this format"
        Write-Host
        Continue
    }

    #To see what your $ReplaceValue is, untag the next line
    #Write-Host Value to be replaced is $ReplaceValue

    $NumberStart=$Serie.NumberRangeStart | ForEach-Object {$_.Replace($ReplaceValue, "")}
    $NumberEnd=$Serie.NumberRangeEnd | ForEach-Object {$_.Replace($ReplaceValue, "")}

    #Convert the range to a Int64 to be able to manager numbers with more than 10 digits
    $NumberStartInt64=[System.Convert]::ToInt64($NumberStart)
    $NumberEndInt64=[System.Convert]::ToInt64($NumberEnd)

    $Ser=$Null
    $Ser= New-Object System.Collections.Arraylist
    [Void]$Ser.Add($NumberStartInt64)
    #$Ser.gettype()
    $Value=$NumberStartInt64+1
    #$Value
    while ($value -lt $NumberEndInt64){
        [Void]$Ser.Add($value)
        $value++
    }

    [Void]$Ser.Add($value)
    #Write-Host $Ser

    #Get all the numbers used in the solution regardless of number range
    $ErrorActionPreference = 'SilentlyContinue'

    $Used=Get-CsUser -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsUser -Filter {PrivateLine -ne $Null} | Select-Object PrivateLine | out-string -stream
    $Used+=Get-CsAnalogDevice -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsCommonAreaPhone -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsExUmContact -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsDialInConferencingAccessNumber -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsTrustedApplicationEndpoint -Filter {LineURI -ne $Null} | Select-Object LineURI | out-string -stream
    $Used+=Get-CsRgsWorkflow | Select-Object LineURI | out-string -stream
    $Used=$Used | ForEach-Object {$_.ToLower()}
    $Used=$Used | ForEach-Object {$_.Replace($ReplaceValue, "")}
    $Used=$Used | ForEach-Object {$_.split(';')[0]}

    $ErrorActionPreference = 'Continue'

    #Find all the numbers that are in use and part of the unassigned number serie
    $AllUsed=@()
    foreach($Series in $Ser){foreach($UsedNumber in $Used){
        if($Series -eq $UsedNumber){$AllUsed+=$UsedNumber}
        }
    }

    #Find all the numbers that are not in use
    $ListUnUsed=@()
    $ComparisonResult=compare-object $Ser $AllUsed
    foreach($UnUsed in $ComparisonResult){
        if($UnUsed.SideIndicator -eq '<='){$ListUnUsed+=$UnUsed.InputObject;$FreeSize++}
    }

    #Find how many free numbers there are in the range
    $RangeSize=($NumberEndInt64-$NumberStartInt64)+1
    $TotalUsed = $RangeSize-$FreeSize
    $TotalFree = $RangeSize-$TotalUsed

    Write-Host "Total free numbers in number range " -nonewline
    Write-Host $Serie.Identity -NoNewLine -Foregroundcolor Green
    Write-Host ", " -NoNewLine
    Write-Host $TotalFree -NoNewLine
    Write-Host " of"$RangeSize
    Write-Host "This range starts with " -NoNewLine
    Write-Host +$NumberStart -NoNewLine -Foregroundcolor Green
    Write-Host " and ends with " -NoNewLine
    Write-Host +$NumberEnd -Foregroundcolor Green

    $FreeSize=$NULL

    #Lists all the unused numbers if L is pressed or just return the list if a Unassigned number serie is specified for the function
    if ($Unassigned -ne $Null){Return $ListUnUsed[1];break}
    else {
            Write-Host "To list available numbers, press "-NoNewLine
            Write-Host "L" -NoNewLine -Foregroundcolor Green
            $opt = Read-Host " else press Enter"
            if($opt -eq "L"){Return $ListUnUsed}
   }

    Write-Host
    $ListUnUsed=$NULL
    $UsedNumbers=$NULL
    $TotalFree=$NULL
    }

    [System.Console]::ForegroundColor = [System.ConsoleColor]::Gray
    $Unassigned=$Null

}

##Edit the input of this function if you want to specify Unassigned Number serie or reuse the script in a enable user scipt
##EXAMPLE: Specify the Unsassigned number range the user belongs to like this: $FristNumber=Get-Unused "Telenor IPT numbers".
##If you do not specify a number range it will go through all number ranges and you get the option which one you will list
##To use this as part of a bigger script to enable users and give them a number automatically you should provide the correct Unassigned Number Identity through a variable
    ##$FristNumber=Get-Unused $UnassingedNumberIdentity

$FirstNumber=Get-Unused #"Oslo"
Write-Host #to give some air in the output
$FirstNumber #outputs the return value from the function

2 thoughts on “SCRIPT: Get-UnusedNumbers.ps1

  1. […] SCRIPT: Get-UnusedNumbers.ps1 [new, 23.04.13] SCRIPT: Set-GlobalVoiceRouting.ps1 SCRIPT: LyncLabOnline – Automated deployment of Lync Server 2013 & Exchange Server 2013  [new, 27.02.13] SCRIPT: Backupscript-EnterpriseEDTv2Lync.ps1 [new, 05.03.13] […]

Leave a Reply

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

WordPress.com Logo

You are commenting using your WordPress.com 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.