Get First X Available DID’s From Unassigned Number Range

This is quite a handy script that will gather the next specified amount of Lync phone numbers (DID’s) within one or more unassigned number ranges.  I also use it as a function for several other more in depth scripts but the guts of it work well for me.

It’s designed to run from within powershell by calling the .ps1 and adding two parameters for the “SiteID” and “FirstX”.  SiteID is used to look up part of the Identity/name of the Unassigned Number range that should make it unique compared to others.  For my purpose it’s an office name but would be whatever you have you ranges named as.  FirstX is the number of DID’s to find.

*Note:  This will search multiple ranges that are flagged with the same name until it retrieves the total amount of DID’s requested.  This is the main reason for making this script.

Save the below text to a .ps1 named whatever makes you smile.  Call that .ps1 in PS and use two parameters.   First parameter is SiteID, the second parameter is FirstX.


‘.\Get First X Available DID in Range.ps1’ MDxx 3

The result will display the range(s) searched and output the total number of available DID’s within that range.  In this case, I wanted 3 phone numbers from all unassigned number ranges that matched “MDxx” within the Identity/name.



#Get only the Next X amount of Available DIDs in a Range then STOP
#Created by Jeff McBride
#Last Update: 7/21/2016
# Fixed private line URI filter issue


$WarningPreference = "SilentlyContinue"
$starttime = get-date
$DIDRange = Get-CsUnassignedNumber | Where-Object {$_.Identity -match $SiteID}
$SelectDID = $null

foreach ($RangeListing in $DIDRange) {
$DIDRangeStart = $RangeListing.NumberRangeStart
$DIDRangeEnd = $RangeListing.NumberRangeEnd
$DIDRangeLike = $DIDRangeEnd + "*"
Write-Host "Searching range:" $RangeListing.Identity

#### Get actively used DID's from all account types
$GetUserLineURI = Get-CSUser -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | select LineURI
$GetUSERPriv = Get-CSUser -Filter {PrivateLine -ge $DIDRangeStart -and PrivateLine -le $DIDRangeEnd -or PrivateLine -like $DIDRangeLike} | select @{N='LineURI';E={($_.PrivateLine)}}
$GetCAP = Get-CSCommonAreaPhone -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | select LineURI
$GetAnalog = Get-CSAnalogDevice -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | select LineURI
$GetWorkFlow = Get-CSRGSWorkflow | Where-Object {$_.LineURI -ge $DIDRangeStart -and $_.LineURI -le $DIDRangeEnd -or $_.LineURI -like $DIDRangeLike} | Select LineURI
$GetEXUMContact = Get-CSEXUMContact -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | Select LineURI
$GetDialInAccess = Get-CsDialInConferencingAccessNumber -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | Select LineURI
$GetMeetingRoom = Get-CSMeetingRoom -Filter {LineURI -ge $DIDRangeStart -and LineURI -le $DIDRangeEnd -or LineURI -like $DIDRangeLike} | Select LineURI

[System.Collections.ArrayList]$CurrentlyAssignedDID = @()
$CurrentlyAssignedDID.Add($GetUserLineURI) > $null
$CurrentlyAssignedDID.Add($GetUserPriv) > $null
$CurrentlyAssignedDID.Add($GetCAP) > $null
$CurrentlyAssignedDID.Add($GetAnalog) > $null
$CurrentlyAssignedDID.Add($GetWorkFlow) > $null
$CurrentlyAssignedDID.Add($GetEXUMContact) > $null
$CurrentlyAssignedDID.Add($GetDialInAccess) > $null
$CurrentlyAssignedDID.Add($GetMeetingRoom) > $null

If ([string]$CurrentlyAssignedDID.length -eq "0 0 0 0 0 0 0 0") {
 $AssignedDIDArray = $null
 Write-Host "No DID's in use within range"
 Else {
 $AssignedDIDlower = $CurrentlyAssignedDID.LineURI.ToLower()
 $AssignedDIDtemp = $AssignedDIDlower.TrimStart("tel:+")
 #This is the final array of all actively assigned DIDs as 11 digits only (US)
 $AssignedDIDArray = $AssignedDIDtemp -replace '(.+?);.+','$1'

###### Setup array of all DIDs within a range regardless of in use or not
$DIDRangeStart = $RangeListing.NumberRangeStart.TrimStart("tel:+")
$DIDRangeEnd = $RangeListing.NumberRangeEnd.TrimStart("tel:+")
$DIDRangeStart = [long]$DIDRangeStart
$DIDRangeEnd = [long]$DIDRangeEnd
$Start = $DIDRangeStart
$End = $DIDRangeEnd

$DIDRangeArray = @()
While ($Start -le $End) {$DIDRangeArray += $Start ; $Start = $Start +1}
##### Determine what count of DIDs are available compared to those used

If ($AssignedDIDArray -eq $null) {
$AssignedDIDArrayUnique = @("00000000000")
 $AvailableDIDArray = Compare-Object $AssignedDIDArrayUnique $DIDRangeArray
 $AvailableDIDArray = $AvailableDIDArray | ? {$_.SideIndicator -eq "=>"}
 Else {
 $AssignedDIDArrayUnique = $AssignedDIDArray | Select -Unique
 $AvailableDIDArray = Compare-Object $AssignedDIDArrayUnique $DIDRangeArray

### Get first available DIDs in first range Else append available into next range to match firstx
If ($SelectDID -eq $null) {
 $SelectDID = $AvailableDIDArray | Select -First $FirstX
 If ($SelectDID.InputObject.Count -ge $FirstX) { break }
 Else {
 $Outcount = $AvailableDIDArray.Count
 Write-Host "There are $Outcount available DID's in this range. Searching next range... "
 Else {
 $AvailableDIDArray = [array]$AvailableDIDArray + $SelectDID
 $SelectDID = $AvailableDIDArray | Select -First $FirstX
 If ($SelectDID.InputObject.Count -ge $FirstX) { break }
 Else {
 Write-Host "There were not $FirstX available DID's within this range..."

Write-Host ""
Write-Host "First available $FirstX DIDs within site" $SiteID

Leave a Reply