Functions/Public/Numbers.ps1
|
# Number, number location, and number range functions Function Get-NectarNumberLocation { <# .SYNOPSIS Returns a list of Nectar DXP service locations used in the DID Management tool. .DESCRIPTION Returns a list of Nectar DXP service locations used in the DID Management tool. .PARAMETER LocationName The name of the service location to get information on. Can be a partial match. To return an exact match and to avoid ambiguity, enclose service location name with ^ at the beginning and $ at the end. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .PARAMETER ResultSize The number of results to return. Defaults to 1000. .EXAMPLE Get-NectarNumberLocation Returns the first 10 service locations .EXAMPLE Get-NectarNumberLocation -ResultSize 100 Returns the first 100 service locations .EXAMPLE Get-NectarNumberLocation -LocationName Location2 Returns up to 10 service locations that contains "location2" anywhere in the name. The search is not case-sensitive. This example would return Location2, Location20, Location214, MyLocation299 etc .EXAMPLE Get-NectarNumberLocation -LocationName ^Location2 Returns up to 10 service locations that starts with "location2" in the name. The search is not case-sensitive. This example would return Location2, Location20, Location214 etc, but NOT MyLocation299 .EXAMPLE Get-NectarNumberLocation -LocationName ^Location2$ Returns a service location explicitly named "Location2". The search is not case-sensitive. .NOTES Version 1.1 #> [Alias("gnnl")] Param ( [Parameter(Mandatory=$False)] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(Mandatory=$False)] [ValidateRange(1,100000)] [int]$ResultSize = 1000 ) Begin { Connect-NectarCloud } Process { Try { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } $URI = "https://$Global:NectarCloud/dapi/numbers/locations?pageNumber=1&tenant=$TenantName&pageSize=$ResultSize&q=$LocationName" Write-Verbose $URI $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader If ($TenantName) {$JSON.elements | Add-Member -Name 'TenantName' -Value $TenantName -MemberType NoteProperty} # Add the tenant name to the output which helps pipelining $JSON.elements | Add-Member -TypeName 'Nectar.Number.LocationList' Return $JSON.elements } Catch { Write-Error "Service location not found. Ensure you typed the name of the service location correctly. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function Set-NectarNumberLocation { <# .SYNOPSIS Update a Nectar DXP service location used in the DID Management tool. .DESCRIPTION Update a Nectar DXP service location used in the DID Management tool. .PARAMETER LocationName The name of the service location to get information on. Can be a partial match. To return an exact match and to avoid ambiguity, enclose location name with ^ at the beginning and $ at the end. .PARAMETER NewLocationName Replace the existing service location name with this one. .PARAMETER ServiceID The service ID associated with the telephony provider for this service location .PARAMETER ServiceProvider The name of the service provider that provides telephony service to this service location .PARAMETER NetworkLocation The phyiscal location for this service location .PARAMETER Notes Can be used for any additional information .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE Set-NectarNumberLocation -LocationName Dallas -ServiceID 44FE98 -ServiceProvider Verizon -Notes "Head office" Returns the first 10 locations .NOTES Version 1.1 #> [Alias("snnl")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)] [Alias("name")] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$NewLocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] $ServiceID, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("provider")] $ServiceProvider, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("location")] $NetworkLocation, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] $Notes, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("id")] [String]$Identity ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($LocationName -And !$Identity) { $LocationInfo = Get-NectarNumberLocation -LocationName $LocationName -Tenant $TenantName -ResultSize 1 $Identity = $LocationInfo.id } If ($LocationInfo.Count -gt 1) { Write-Error "Multiple number locations found that match $LocationName. Please refine your location name search query. $($_.Exception.Message)" Break } If ($NewLocationName) {$LocationName = $NewLocationName} If (-not $ServiceID) {$ServiceID = $LocationInfo.ServiceId} If (-not $ServiceProvider) {$ServiceProvider = $LocationInfo.provider} If (-not $NetworkLocation) {$NetworkLocation = $LocationInfo.location} If (-not $Notes) {$Notes = $LocationInfo.notes} $URI = "https://$Global:NectarCloud/dapi/numbers/location/$Identity/?tenant=$TenantName" Write-Verbose $URI $Body = @{ name = $LocationName serviceId = $ServiceID provider = $ServiceProvider location = $NetworkLocation notes = $Notes } $JSONBody = $Body | ConvertTo-Json Try { $NULL = Invoke-RestMethod -Method PUT -URI $URI -Headers $Global:NectarAuthHeader -Body $JSONBody -ContentType 'application/json; charset=utf-8' Write-Verbose $JSONBody } Catch { Write-Error "Unable to apply changes for location $LocationName. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function New-NectarNumberLocation { <# .SYNOPSIS Create a new Nectar Service Location for DID Management used in the DID Management tool. .DESCRIPTION Create a new Nectar Service Location for DID Management used in the DID Management tool. .PARAMETER LocationName The name of the new service location. Must be unique. .PARAMETER ServiceID The service ID for telephony services at the newservice location. Can be used as desired. Not required. .PARAMETER ServiceProvider The service provider for telephony services at the newservice location. Can be used as desired. Not required. .PARAMETER ServiceProvider The network location to associate with the newservice location. Can be used as desired. Not required. .PARAMETER Notes Any relevent notes about the service location. Can be used as desired. Not required. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE New-NectarNumberLocation -LocationName Dallas -ServiceID 348FE22 -ServiceProvider Verizon -NetworkLocation Dallas -Notes "This is headquarters" .NOTES Version 1.1 #> [Alias("nnnl")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("name")] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$ServiceID, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("provider")] [string]$ServiceProvider, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("location")] [string]$NetworkLocation, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$Notes, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } $URI = "https://$Global:NectarCloud/dapi/numbers/location/?tenant=$TenantName" Write-Verbose $URI $Body = @{ name = $LocationName serviceId = $ServiceID provider = $ServiceProvider location = $NetworkLocation notes = $Notes } $JSONBody = $Body | ConvertTo-Json Try { Invoke-RestMethod -Method POST -URI $URI -Headers $Global:NectarAuthHeader -Body $JSONBody -ContentType 'application/json; charset=utf-8' Write-Verbose $JSONBody } Catch { Write-Error "Unable to create service location $LocationName. The service location may already exist. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function Remove-NectarNumberLocation { <# .SYNOPSIS Removes one or more service locations in the DID Management tool. .DESCRIPTION Removes one or more service locations in the DID Management tool. .PARAMETER LocationName The name of the number service location to remove. .PARAMETER Identity The numerical ID of the number service location. Can be obtained via Get-NectarNumberLocation and pipelined to Remove-NectarNumberLocation .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE Remove-NectarNumberLocation Tokyo Removes the Toyota location. The command will fail if the location has number ranges assigned. .NOTES Version 1.1 #> [Alias("rnnl")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("id")] [string]$Identity ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($LocationName -And !$Identity) { $Identity = (Get-NectarNumberLocation -LocationName $LocationName -Tenant $TenantName -ResultSize 1 -ErrorVariable GetLocationError).ID } If ($Identity.Count -gt 1) { Write-Error "Multiple number locations found that match $LocationName. Please refine your location name search query." Break } If (!$GetLocationError) { $URI = "https://$Global:NectarCloud/dapi/numbers/location/$Identity/?tenant=$TenantName" Write-Verbose $URI Try { $NULL = Invoke-RestMethod -Method DELETE -URI $URI -Headers $Global:NectarAuthHeader Write-Verbose "Successfully deleted $LocationName." } Catch { Write-Error "Unable to delete service location $LocationName. Ensure you typed the name of the service location correctly and that the service location has no assigned ranges. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } } ################################################################################################################################################# # # # DID Number Range Management Functions # # # Function Get-NectarNumberRange { <# .SYNOPSIS Returns a list of Nectar DXP number ranges in the DID Management tool .DESCRIPTION Returns a list of Nectar DXP ranges in the DID Management tool .PARAMETER RangeName The name of the number range to get information on. Can be a partial match. To return an exact match and to avoid ambiguity, enclose range name with ^ at the beginning and $ at the end. .PARAMETER LocationName The name of the location to get information on. Will be an exact match. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .PARAMETER ResultSize The number of results to return. Defaults to 1000. .EXAMPLE Get-NectarNumberRange Returns the first 10 number ranges .EXAMPLE Get-NectarNumberRange -ResultSize 100 Returns the first 100 number ranges .EXAMPLE Get-NectarNumberRange -LocationName Tokyo Returns the first 10 number ranges at the Tokyo location .EXAMPLE Get-NectarNumberRange -RangeName Range2 Returns up to 10 ranges that contains "range2" anywhere in the name. The search is not case-sensitive. This example would return Range2, Range20, Range214, MyRange299 etc .EXAMPLE Get-NectarNumberRange -RangeName ^Range2 Returns up to 10 ranges that starts with "range2" in the name. The search is not case-sensitive. This example would return Range2, Range20, Range214 etc, but NOT MyRange299. .EXAMPLE Get-NectarNumberRange -RangeName ^Range2$ Returns any range explicitly named "Range2". The search is not case-sensitive. This example would return Range2 only. If there are multiple ranges with the name Range2, all will be returned. .EXAMPLE Get-NectarNumberRange -RangeName ^Range2$ -LocationName Tokyo Returns a range explicitly named "Range2" in the Tokyo location. The search is not case-sensitive. .NOTES Version 1.1 #> [Alias("gnnr")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$RangeName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(Mandatory=$False)] [ValidateRange(1,100000)] [int]$ResultSize = 1000 ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($LocationName) { $LocationID = (Get-NectarNumberLocation -LocationName "$LocationName" -Tenant $TenantName -ErrorVariable LocError).ID } If ($LocError) { Break} $URI = "https://$Global:NectarCloud/dapi/numbers/ranges?pageNumber=1&tenant=$TenantName&pageSize=$ResultSize&serviceLocationId=$LocationID&q=$RangeName" Write-Verbose $URI Try { $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader If ($TenantName) {$JSON.elements | Add-Member -Name 'TenantName' -Value $TenantName -MemberType NoteProperty} # Add the tenant name to the output which helps pipelining $JSON.elements | Add-Member -TypeName 'Nectar.Number.RangeList' Return $JSON.elements } Catch { Write-Error "An error occurred. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function Set-NectarNumberRange { <# .SYNOPSIS Make changes to a Nectar range for DID Management .DESCRIPTION Make changes to a Nectar range for DID Management .PARAMETER RangeName The name of the range. Must be unique. .PARAMETER RangeType The type of range. Can be either STANDARD (for DID ranges) or EXTENSION (for extension-based ranges). .PARAMETER FirstNumber The first number in a STANDARD range. Must be numeric, but can start with +. .PARAMETER LastNumber The last number in a STANDARD range. Must be numeric, but can start with +. Must be larger than FirstNumber, and must have the same number of digits. .PARAMETER BaseNumber The base DID for an EXTENSION range. Must be numeric, but can start with +. .PARAMETER ExtStart The first extension number in an EXTENSION range. Must be numeric. .PARAMETER ExtEnd The last extension number in an EXTENSION range. Must be numeric. Must be larger than ExtStart, and must have the same number of digits. .PARAMETER RangeSize The number of phone numbers/extensions in a range. Can be used instead of LastNumber/ExtEnd. .PARAMETER HoldDays The number of days to hold a newly-freed number before returning it to the pool of available numbers. .PARAMETER LocationName The service location to assign the range to. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE Set-NectarNumberRange -RangeName DIDRange1 -RangeType STANDARD -FirstNumber +15552223333 -LastNumber +15552224444 -LocationName Dallas Edits a DID range for numbers that fall in the range of +15552223333 to +15552224444 .NOTES Version 1.1 #> [Alias("snnr")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("name")] [string]$RangeName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidateSet("STANDARD","EXTENSION", IgnoreCase=$True)] [Alias("type")] [string]$RangeType, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] # [ValidatePattern("^(\+|%2B)?\d+$")] [string]$FirstNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] # [ValidatePattern("^(\+|%2B)?\d+$")] [string]$LastNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] # [ValidatePattern("^(\+|%2B)?\d+$")] [string]$BaseNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] # [ValidatePattern("^\d+$")] [string]$ExtStart, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] # [ValidatePattern("^\d+$")] [string]$ExtEnd, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [int]$RangeSize, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [int]$HoldDays = 0, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)] [Alias("serviceLocationId")] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("id")] [int]$Identity ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($RangeName -And !$Identity) { $RangeInfo = Get-NectarNumberRange -RangeName $RangeName -Tenant $TenantName -ResultSize 1 $Identity = $RangeInfo.id If ($NewRangeName) {$RangeName = $NewRangeName} If (-not $FirstNumber) {$FirstNumber = $RangeInfo.firstNumber} If (-not $LastNumber) {$LastNumber = $RangeInfo.lastNumber} If (-not $RangeType) {$RangeType = $RangeInfo.type} If (-not $HoldDays) {$HoldDays = $RangeInfo.holdDays} If (-not $BaseNumber) {$BaseNumber = $RangeInfo.baseNumber} If (-not $ExtStart) {$ExtStart = $RangeInfo.extStart} If (-not $ExtEnd) {$ExtEnd = $RangeInfo.extEnd} # If (-not $LocationName) {$LocationID = $RangeInfo.serviceLocationId} } $LocationID = (Get-NectarNumberLocation -LocationName "$LocationName" -Tenant $TenantName -ErrorVariable LocError).ID $URI = "https://$Global:NectarCloud/dapi/numbers/range/$Identity/?tenant=$TenantName" Write-Verbose $URI $Body = @{ name = $RangeName type = $RangeType holdDays = $HoldDays serviceLocationId = $LocationID } If ($FirstNumber) { $Body.Add('firstNumber', $FirstNumber) } If ($LastNumber) { $Body.Add('lastNumber', $LastNumber) } If ($BaseNumber) { $Body.Add('baseNumber', $BaseNumber) } If ($ExtStart) { $Body.Add('extStart', $ExtStart) } If ($ExtEnd) { $Body.Add('extEnd', $ExtEnd) } If ($RangeSize) { $Body.Add('rangeSize', $RangeSize) } $JSONBody = $Body | ConvertTo-Json Try { $NULL = Invoke-RestMethod -Method PUT -URI $URI -Headers $Global:NectarAuthHeader -Body $JSONBody -ContentType 'application/json; charset=utf-8' Write-Verbose $JSONBody } Catch { Write-Error "Unable to apply changes for range $RangeName. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function New-NectarNumberRange { <# .SYNOPSIS Create a new Nectar range for DID Management .DESCRIPTION Create a new Nectar range for DID Management .PARAMETER RangeName The name of the new range. Must be unique. .PARAMETER RangeType The type of range. Can be either STANDARD (for DID ranges) or EXTENSION (for extension-based ranges). .PARAMETER FirstNumber The first number in a STANDARD range. Must be numeric, but can start with +. .PARAMETER LastNumber The last number in a STANDARD range. Must be numeric, but can start with +. Must be larger than FirstNumber, and must have the same number of digits. .PARAMETER BaseNumber The base DID for an EXTENSION range. Must be numeric, but can start with +. .PARAMETER ExtStart The first extension number in an EXTENSION range. Must be numeric. .PARAMETER ExtEnd The last extension number in an EXTENSION range. Must be numeric. Must be larger than ExtStart, and must have the same number of digits. .PARAMETER RangeSize The number of phone numbers/extensions in a range. Can be used instead of LastNumber/ExtEnd. .PARAMETER HoldDays The number of days to hold a newly-freed number before returning it to the pool of available numbers. .PARAMETER LocationName The location to assign the range to. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE New-NectarNumberRange -RangeName DIDRange1 -RangeType STANDARD -FirstNumber +15552223333 -LastNumber +15552224444 -LocationName Dallas Creates a DID range for numbers that fall in the range of +15552223333 to +15552224444 .EXAMPLE New-NectarNumberRange -RangeName DIDRange1 -RangeType STANDARD -FirstNumber +15552223000 -RangeSize 1000 -LocationName Dallas Creates a DID range for numbers that fall in the range of +15552223000 to +15552223999 .EXAMPLE New-NectarNumberRange -RangeName ExtRange1 -RangeType EXTENSION -BaseNumber +15552223000 -ExtStart 2000 -ExtEnd 2999 -LocationName Dallas Creates an extension range for numbers that fall in the range of +15552223000 x2000 to x2999 .NOTES Version 1.2 #> [Alias("nnnr")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)] [Alias("name")] [string]$RangeName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)] [ValidateSet("STANDARD","EXTENSION", IgnoreCase=$True)] [string]$RangeType, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidatePattern("^(\+|%2B)?\d+$")] [string]$FirstNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidatePattern("^(\+|%2B)?\d+$")] [string]$LastNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidatePattern("^(\+|%2B)?\d+$")] [string]$BaseNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidatePattern("^\d+$")] [string]$ExtStart, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidatePattern("^\d+$")] [string]$ExtEnd, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [int]$RangeSize, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [int]$HoldDays, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$True)] [string]$LocationName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("id")] [int]$Identity ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } $LocationID = (Get-NectarNumberLocation -LocationName $LocationName -Tenant $TenantName -ErrorVariable NumLocError).ID If ($LocationID.Count -gt 1) { Write-Error "Multiple locations found that match $LocationName. Please refine your location name search query" Break } $URI = "https://$Global:NectarCloud/dapi/numbers/range?tenant=$TenantName" Write-Verbose $URI $Body = @{ name = $RangeName type = $RangeType holdDays = $HoldDays serviceLocationId = $LocationID } If ($FirstNumber) { $Body.Add('firstNumber', $FirstNumber) } If ($LastNumber) { $Body.Add('lastNumber', $LastNumber) } If ($BaseNumber) { $Body.Add('baseNumber', $BaseNumber) } If ($ExtStart) { $Body.Add('extStart', $ExtStart) } If ($ExtEnd) { $Body.Add('extEnd', $ExtEnd) } If ($RangeSize) { $Body.Add('rangeSize', $RangeSize) } $JSONBody = $Body | ConvertTo-Json Try { Invoke-RestMethod -Method POST -URI $URI -Headers $Global:NectarAuthHeader -Body $JSONBody -ContentType 'application/json; charset=utf-8' Write-Verbose $JSONBody } Catch { Write-Error "Unable to create range $RangeName. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function Remove-NectarNumberRange { <# .SYNOPSIS Removes one or more ranges from a service location in the DID Management tool. .DESCRIPTION Removes one or more ranges from a service location in the DID Management tool. .PARAMETER RangeName The name of the number range to remove. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .PARAMETER Identity The numerical ID of the number range. Can be obtained via Get-NectarNumberRange and pipelined to Remove-NectarNumberRange .EXAMPLE Remove-NectarNumberRange Range1 Removes the range Range1 .NOTES Version 1.1 #> [Alias("rnnr")] Param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$RangeName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [Alias("id")] [String]$Identity ) Begin { Connect-NectarCloud } Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($RangeName -And !$Identity) { $Identity = (Get-NectarNumberRange -RangeName $RangeName -Tenant $TenantName -ErrorVariable GetRangeError).ID } If ($Identity.Count -gt 1) { Write-Error "Multiple ranges found that match $RangeName. Please refine your range name search query" Break } If (!$GetRangeError) { $URI = "https://$Global:NectarCloud/dapi/numbers/range/$Identity/?tenant=$TenantName" Write-Verbose $URI Try { $NULL = Invoke-RestMethod -Method DELETE -URI $URI -Headers $Global:NectarAuthHeader Write-Verbose "Successfully deleted $RangeName number range." } Catch { Write-Error "Unable to delete $RangeName number range. Ensure you typed the name of the range correctly. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } } ################################################################################################################################################# # # # DID Number Management Functions # # # Function Get-NectarNumber { <# .SYNOPSIS Returns a list of Nectar DXP numbers from the DID Management tool .DESCRIPTION Returns a list of Nectar DXP numbers from the DID Management tool .PARAMETER PhoneNumber The phone number to return information about. Can be a partial match. To return an exact match and to avoid ambiguity, enclose number with ^ at the beginning and $ at the end. .PARAMETER LocationName The name of the location to get number information about. Will be an exact match. .PARAMETER RangeName The name of the range to get number information about. Will be an exact match. .PARAMETER NumberState Returns information about numbers that are either USED, UNUSED or RESERVED .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .PARAMETER ResultSize The number of results to return. Defaults to 1000. .EXAMPLE Get-NectarNumber Returns the first 10 numbers .EXAMPLE Get-NectarNumber -ResultSize 100 Returns the first 100 numbers .EXAMPLE Get-NectarNumber -LocationName Tokyo Returns the first 10 numbers at the Tokyo location .EXAMPLE Get-NectarNumber -RangeName Range2 Returns up to 10 numbers from a number range called Range2. .EXAMPLE Get-NectarNumber -RangeName Range2 -NumberState UNUSED -ResultSize 100 Returns up to 100 unused numbers in the Range2 range. .NOTES Version 1.1 #> [Alias("gnn")] Param ( [Parameter(Mandatory=$False)] [ValidatePattern("^(\+|%2B)?\d+$")] [string]$PhoneNumber, [Parameter(Mandatory=$False)] [string]$LocationName, [Parameter(Mandatory=$False)] [string]$RangeName, [Parameter(Mandatory=$False)] [ValidateSet("USED","UNUSED","RESERVED", IgnoreCase=$True)] [string]$NumberState, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(Mandatory=$False)] [ValidateRange(1,100000)] [int]$PageSize = 10000, [Parameter(Mandatory=$False)] [ValidateRange(1,100000)] [int]$ResultSize ) Begin { Connect-NectarCloud } Process { Try { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($LocationName) { $LocationID = (Get-NectarNumberLocation -LocationName ^$LocationName$ -Tenant $TenantName -ResultSize 1 -ErrorVariable NectarError).ID } If ($RangeName) { $RangeID = (Get-NectarNumberRange -RangeName $RangeName -LocationName $LocationName -Tenant $TenantName -ResultSize 1 -ErrorVariable +NectarError).ID } If ($PhoneNumber) { # Replace + with %2B if present $PhoneNumber = $PhoneNumber.Replace("+", "%2B") } $URI = "https://$Global:NectarCloud/dapi/numbers/" Write-Verbose $URI $Params = @{ 'orderByField' = 'number' 'orderDirection' = 'asc' } If ($ResultSize) { $Params.Add('pageSize', $ResultSize) } Else { $Params.Add('pageSize', $PageSize) } If ($LocationID) { $Params.Add('serviceLocationId', $LocationID) } If ($RangeID) { $Params.Add('numbersRangeId', $RangeID) } If ($NumberState) { $Params.Add('states', $NumberState) } If ($PhoneNumber) { $Params.Add('q', $PhoneNumber) } If ($TenantName) { $Params.Add('Tenant', $TenantName) } If (!$NectarError) { $JSON = Invoke-RestMethod -Method GET -URI $URI -Headers $Global:NectarAuthHeader -Body $Params If ($TenantName) { $JSON.elements | Add-Member -Name 'TenantName' -Value $TenantName -MemberType NoteProperty } # Add the tenant name to the output which helps pipelining $JSON.elements | Add-Member -TypeName 'Nectar.Number.List' $JSON.elements $TotalPages = $JSON.totalPages If ($TotalPages -gt 1 -and !($ResultSize)) { $PageNum = 2 Write-Verbose "Page size: $PageSize" While ($PageNum -le $TotalPages) { Write-Verbose "Working on page $PageNum of $TotalPages" $PagedURI = $URI + "?pageNumber=$PageNum" $JSON = Invoke-RestMethod -Method GET -URI $PagedURI -Headers $Global:NectarAuthHeader -Body $Params If ($TenantName) { $JSON.elements | Add-Member -Name 'TenantName' -Value $TenantName -MemberType NoteProperty } $JSON.elements | Add-Member -TypeName 'Nectar.Number.List' $JSON.elements $PageNum++ } } } } Catch { Write-Error "Unable to retrieve number information. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } Function Set-NectarNumber { <# .SYNOPSIS Makes changes to one or more phone numbers. .DESCRIPTION Makes changes to one or more phone numbers. .PARAMETER PhoneNumber A phone number to make changes to. Must be an exact match. .PARAMETER NumberState Change the state of a phone number to either UNUSED or RESERVED. A number marked USED cannot be modified. .PARAMETER Comment A comment to add to a reserved phone number. .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE Set-NectarNumber +12223334444 -NumberState RESERVED Reserves the number +12223334444 .NOTES Version 1.1 #> [Alias("snn")] Param ( [Parameter(ValueFromPipelineByPropertyName,Mandatory=$False)] [ValidatePattern("^(\+|%2B)?\d+$")] [string]$PhoneNumber, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidateSet("UNUSED","RESERVED", IgnoreCase=$True)] [string]$NumberState, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [ValidateLength(0,254)] [string]$Comment, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName, [Parameter(ValueFromPipelineByPropertyName)] [Alias("id")] [String]$Identity ) Process { # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } If ($PhoneNumber -And !$Identity) { $Identity = (Get-NectarNumber -PhoneNumber $PhoneNumber -Tenant $TenantName -ResultSize 1 -ErrorVariable PhoneNumError).ID } If (!$PhoneNumError) { $URI = "https://$Global:NectarCloud/dapi/numbers/$Identity/state?state=$NumberState&tenant=$TenantName" Write-Verbose $URI If (($Comment) -And ($NumberState -eq "RESERVED")) { # Convert special characters to URI-compatible versions #$Comment = [uri]::EscapeDataString($Comment) $URI += "&comment=$Comment" } Try { $NULL = Invoke-RestMethod -Method PUT -URI $URI -Headers $Global:NectarAuthHeader Write-Verbose "Successfully applied changes to $PhoneNumber." } Catch { Write-Error "Unable to apply changes for phone number $PhoneNumber. The number may already be in the desired state. $($_.Exception.Message)" If ($PSCmdlet.MyInvocation.BoundParameters["ErrorAction"] -ne "SilentlyContinue") { Get-JSONErrorStream -JSONResponse $_ } } } } } Function Get-NectarUnallocatedNumber { <# .SYNOPSIS Returns the next available number in a given location/range. .DESCRIPTION Returns the next available number in a given location/range. .PARAMETER LocationName The service location to return a number for .PARAMETER RangeName The range to return a number for .PARAMETER TenantName The name of the Nectar DXP tenant. Used in multi-tenant configurations. .EXAMPLE Get-NectarUnallocatedNumber -RangeName Jericho Returns the next available number in the Jericho range. .NOTES Version 1.1 #> [Alias("gnun")] Param ( [Parameter(Mandatory=$False)] [string]$LocationName, [Parameter(Mandatory=$False)] [string]$RangeName, [Parameter(ValueFromPipelineByPropertyName, Mandatory=$False)] [string]$TenantName ) # Use globally set tenant name, if one was set and not explicitly included in the command If ($Global:NectarTenantName -And !$PSBoundParameters.ContainsKey('TenantName')) { $TenantName = $Global:NectarTenantName } ElseIf ($TenantName) { If ($TenantName -NotIn $Global:NectarTenantList) { $TList = $Global:NectarTenantList -join ', ' Throw "Could not find a tenant with the name $TenantName on https://$Global:NectarCloud. Select one of $TList. $($_.Exception.Message)" } } $NextFreeNum = Get-NectarNumber -LocationName $LocationName -RangeName $RangeName -NumberState UNUSED -Tenant $TenantName -ResultSize 1 If ($NextFreeNum) { Return $NextFreeNum } Else { Write-Error "No available phone number found." } } |