Is that Skype for Business (Lync) Number Free?

Get-CsAdPrincipal is a tragically underused cmdlet. Absent a fully generic Get-CsEndpointObject, it’s the next best thing to Get-ADObject, and is killer when you have no idea what you’re looking for – a User, a Common Area Phone, Conference Dialin Number, Response Group or some crazy custom endpoint used in a Skype-enabled application, especially if all you care about is seeing if a number is available. If you see “485 Ambiguous” in a SIP trace, this will help you figure out who (and/or what) all has this number, and why Skype isn’t quite sure which one the caller wanted to reach.

There are several scripts for testing each of the Skype for Business object types one by one, and I give some of my favorites at the end of the post; the Get-CsAdPrincipal approach is faster in automation if you’re mostly interested in whether a number is consumed at all, and aren’t concerned with *what* exactly is consuming it.

Get-CsAdPrincipal -LDAPFilter '|(msrtcsip-line=tel:+499112224000*)(msrtcsip-privateline=tel:+499112224000*)'

The LDAP query is checking both the MsRTCSIP-Line and MsRTCSIP-PrivateLine attributes, and there is an asterisk at the end in case the extension was specified separately: tel:+499112224000 and tel:+499112224000;ext=4000 are functionally the same number, but do not look the same to Skype for Business! This is common in places where each line can be directly dialed from outside – that is, much of Europe. I used the attribute names in all lowercase because the mixed-case versions did not work.

If all you wanted was a quick way to check if a number is free or not, you can quit reading now and get back to writing your provisioning script 🙂 If you want to know a bit more about Skype for Business objects, as well as see some really nice stuff for viewing your number pool, stay with me…

From there, if you do want to make changes to the object consuming the number, it takes a little knowledge to interpret the result and get the Cs* object to change the phone number. WARNING: Do NOT write MsRTCSIP-Line directly in AD – it might appear to work, but is completely unsupported.

First, just seeing the DisplayName and SipAddress might make it clear enough to you, especially if you’ve been careful about your naming schemes.

Next, look at the ObjectClass: {top, person, organizationalPerson, user}  is an AD User object. As far as I know, Skype for Business uses that only for CsUser and endpoints for third-party applications that have chosen to authenticate as AD Users (AudioCodes’ IVR running as a VM in their SBA, for example). Just about everything else will be {top, person, organizationalPerson, contact}: Common Area Phones, Response Groups, Conference Dialin Numbers, Analog Devices, weird custom endpoints.

Finally, look at where it lives: DistinguishedName/Identity (they’re identical).

  • If it’s in your regular AD structure and is a Contact object, it’s most likely a Common Area Phone (Get-CsCommonAreaPhone) or Analog Device (Get-CsAnalogDevice – reference to a fax or other device that can’t play directly with Skype), perhaps Exchange Unified Messaging (Get-CsExUmContact).
  • If it’s in CN=Application Contacts,CN=RTC Service,CN=Services,CN=Configuration,DC=yourawesomedomain,DC=com, then it is a Dialin Conference Number or Response Group, which can be found by piping into Get-CsApplicationEndpoint like so:
Get-CsAdPrincipal -LDAPFilter '|(msrtcsip-line=tel:+499112224000*)(msrtcsip-privateline=tel:+499112224000*)' | Get-CsApplicationEndpoint


Look at OwnerUrn: urn:application:RGS is a Response Group (Get-CsRGSWorkflow), urn:application:Caa is a Conference Dialin Number (Get-CsDialinConferencingAccessNumber).


Other approaches that involve directly getting the manipulable Cs* objects consuming the number but are slower (and probably overkill) if you just want to test if the number is free: (StĂĄle Hansen: great reports about which numbers are consumed and which ones are free) (Greig Sheridan added a comfortable front end to StĂĄle’s script) (Lasse Wedø gets you the manipulable object consuming the number) (A view of your number pool by Lasse Wedø)

Anything awesome that I’m missing?





6 thoughts on “Is that Skype for Business (Lync) Number Free?

  1. Pingback: Is that Skype for Business (Lync) Number Free? | Mandie’s Memos | JC's Blog-O-Gibberish
  2. Here is something very similar but done a different way. It requires more work though it may be a touch faster. My home domain is way too tiny to do a speed test.

    #This will grab all Nashville, TN phone objects by area code
    #Automagically find a Global Catalog in this AD Site
    $gcLocator = Get-ADDomainController -SiteName ([System.DirectoryServices.ActiveDirectory.ActiveDirectorySite]::GetComputerSite().Name) -Discover
    [string]$gc = $gcLocator.Hostname
    $gc = $gc + “:3268”

    $ErrorActionPreference = “SilentlyContinue”
    $myArray = @()
    #Build array, filtered on the 2 area codes for Nashville, TN
    #615 area code
    $myArray += Get-ADObject -Server $gc -SearchBase ‘DC=flinchbot,DC=com’ -ldapFilter (‘msRTCSIP-Line=tel:+1615*’) -Properties *
    #629 area code
    $myArray += Get-ADObject -Server $gc -SearchBase ‘DC=flinchbot,DC=com’ -ldapFilter (‘msRTCSIP-Line=tel:+1629*’) -Properties *
    #Spit out the account and phone number.
    $myarray | select canonicalname, msrtcsip-line

    Liked by 1 person

    • Shockingly, yours was FAR slower in my huge work environment:

      Measure-Command { $results = Get-CsAdPrincipal -LDAPFilter ‘|(msrtcsip-line=tel:+49911222*)(msrtcsip-privateline=tel:+49911222*)’ }

      881 ms for 391 results

      Measure-Command { $myArray = @() … $myarray | select canonicalname, msrtcsip-line }
      29445 ms for 390 results (flubbed the LDAP query for both msrtcsip-line and -privateline)

      Note: I had to run the Get-AdObject twice to check both our regular user domain and the root domain, where for reasons I wasn’t around for, all of the Response Groups and Dialin Conferencing numbers ended up.

      Will try to optimize yours a bit, because I agree, it *should* be faster. But maybe Skype for Business is doing a super-good job in searching AD.


  3. Pingback: UC Unleashed » Function: Get-CsPhoneNumberAssignment – Find Where a Number is Assigned in Skype for Business
  4. This looks like a great solution for finding if a number is free to use, I want to add it to my provisioning script. I have it working for a single number but I’m struggling to get it working passing a variable to the command.

    Get-CsAdPrincipal -LDAPFilter ‘|(msrtcsip-line=tel:+499112224000*)(msrtcsip-privateline=tel:+499112224000*)’

    Not Working
    $number = “+499112224000”
    Get-CsAdPrincipal -LDAPFilter ‘|(msrtcsip-line=tel:$number*)(msrtcsip-privateline=tel:$number*)’

    Any help to get it working would be greatly appreciated.


Write your own memo:

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

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