Documentation is important. It’s key to being able to work together in teams and not have to rely on information based informally from person to person. I’ve talked before about how to document your PowerShell scripts but did you know you can also label each DID on your ThinkTel SIP trunk? This lets you record who or what the DID is for and can be very useful since it is shown in CDR reports, letting you know who originated or received individual calls. This can also be a big step towards not needing to document your phone number assignments in a separate Excel spreadsheet.

While the script below is specifically for Microsoft Lync or Skype for Business, it could easily be adapted for any system where the information on the allocated DID and the assigned user was available using PowerShell. This could be a backend database, a directory of some kind or web service API.

One note, and you’ll see this below too, I’m using Invoke-RestMethod here so this will need to be run on a machine with PowerShell 3.0+ since that’s when this cmdlet was introduced. This was released with Windows 2012 R1 so hopefully you have at least that. If you did have Windows 2008 R2 for some reason, my sympathies, but you could use System.Net.WebClient instead. If anyone has this situation, and is interested in a version of this script for PowerShell 2.0, let me know.

Get Labels From Skype for Business

Next step, again using previously shown PowerShell (see Managing Your Lync Phone Numbers), we get a list of all numbers assigned and a label to represent to what they are assigned to.

For users, the choice of label is obvious (name and SIP address), and for other objects there is generally a description or display name available. In a worse case scenario, I find it sufficient to just note the kind of usage.

Find Updates

Then we compare the two hashes:
* We check for any labels that are only in the current set; those are ones that don’t exist on the SIP trunk since at worse an empty label would be returned for each DID,
* We check for any labels that are only in the existing set; those are old ones that don’t exist in Skype for Business,
* We check all the labels in both to see if they match, other wise we update it

$newLabels = @{}
foreach($num in $currentLabels.Keys) {
if($existingLabels.ContainsKey($num)) {
# this is a valid number on the trunk
if($currentLabels[$num] -ne $existingLabels[$num]) {
# the label needs to be updated
$newLabels.Add($num, $currentLabels[$num])
}
} else {
# this is not a number on the trunk
Write-Warning "Skipping $num since it isn't on the trunk"
}
}

You might wonder why I’m downloading each DID instead of just building it the response in memory. The initial GET query we did for all the DIDs doesn’t have all the information for the DID. So features like number translation would be over-written if we didn’t include it in the PUT body. You can see the difference since the initial GET query doesn’t return an ArrayOfDid, instead it’s an ArrayOfTerseNumber, with TerseNumber only having Number and Label instead of all the DID information.