Surface Hub – Skype for Business Login Failure

Excitement has grown around the Kloud office of late as each state waits with anticipation of a Surface Hub arriving to connect to our Skype for Business environment. The 84 inch Surface Hub destined for our Adelaide Boardroom which I nicknamed ‘Godzilla’ has had only one problem since installation, it fails to login to Skype for Business. Which makes this device go from a high end meeting room endpoint to a what I could only say is a giant tablet for games of tick tac toe, therefore this became my problem rather quickly. Everything seemed so pleasant following the initial steps from the out of box experience (OOBE). The Hub asked me questions, I responded politely with what I thought were all the right answers with a big smile on my face.

You could feel the electricity in the air.

This first date was going pretty smoothly I thought. Maybe the Hub caught wind of the nickname I was calling it around the water cooler in the office, because after our first date and the Hub launched into its standard meeting experience, an error was presented. Skype for Business would timeout and eventually say ‘login failure‘.

Oh dear!

A quick look around the Hub’s administrative settings I could see that the account configured for mail was saying ‘synced‘ and I could verify this with a quick white board and ‘send to email‘, which arrived promptly to my inbox. Furthermore with my laptop in toe I could successfully login to a Skype for Business soft client with the Hub’s credentials. What is unique to the Hub client is that its does some extra validation on the account over other SFB clients that I’m familiar with. I’ll explain..

The device account I had for the Hub was in the ‘‘ SIP domain, but the Active Directory (AD) FQDN of the connected servers was different. In Kloud’s circumstance I didn’t think much of this issue as our Hub was logging in over an internet connection through the Edge Server that has an access FQDN of to me were the same domain. A quick login to the Edge Server logs didn’t present many results of an attempt of SIP from The Hub was using autodiscover to kick off the process of login to I knew that much and must be failing. Using the Remote Connectivity Analyser (RCA) I could verify the login process for the account was successful and green ticks appeared against all lines. I thought to myself

What have I said to Godzilla to hurts its feeling so badly? That it deliberately wants to make my life hard

If you run a Skype for Business Autodiscover Web Service test on the following process is attempted to the Autodiscover Web Service URL:

  1. Attempting to resolve the host name in DNS.
  2. Testing TCP port 443 on host to ensure it’s listening and open
  3. Testing the SSL certificate to make sure it’s valid
  4. Host name was found in the Certificate Subject Alternative Name entry
  5. Testing HTTPS authentication methods for URL
    HTTP authentication methods successful.
  6. Testing HTTP content for URL has token=”User”.
  7. Found as expected token=”User” and confirmed anonymous access not allowed.
    HTTP Response Headers:
    Connection: Keep-Alive
    Pragma: no-cache
    X-MS-Server-Fqdn: AUSFBFE01.domain.local
    X-MS-Correlation-Id: 2147484240
    client-request-id: b6d465f4-f318-485e-8d3e-06b32524fd3d
    X-Content-Type-Options: nosniff
    Content-Length: 1047
    Cache-Control: no-cache
    Content-Type: application/; v=1
    Date: Sat, 25 Mar 2017 11:49:23 GMT
    Expires: -1
    Elapsed Time: 127 ms.

In the above web request Lyncdiscover told the Hub that the registrar server its connecting to has a X-MS-Server-Fqdn with domain.local, which it did not automatically trust. Microsoft do state this in an article:

  • Multiple DNS suffixes – When your Skype for Business infrastructure has disjointed namespaces such that one or more servers have a DNS suffix that doesn’t match the suffix of the sign-in address (SIP) for Skype for Business.

followed by examples:


You can type multiple domain names, separated by commas.
For example:,,

For some reason it didn’t click with me as these are all domains used for Office 365 that are publicly accessible DNS zones. My logic was that we were connecting via edge ‘‘ and I had a ‘‘ I wouldn’t need anything added because my SIP Address = Edge FQDN domain, plus its bound to matching SAN entries in a publicly signed certificate. Kloud isn’t a hosting provider that services thousands of SIP domains like Office 365 which it cannot have in its edge certificate as Microsoft aren’t authoritative for. This is why Office 365 get customers to add CNAME’s to their endpoints and perform 80 to 443 port wizardry where possible, allowing clients to bind SSL to correct Microsoft service names.

What Microsoft are trying to say is

If your SFB SIP domain doesn’t match your Active Directory infrastructure domain name that your SFB servers are joined to, you need to add via the following

Add ‘domain.local‘ into the Hub via Settings -> This Device -> Calling

Lastly, this doesn’t matter if your logging the Hub in via the internet or internal LAN, you will get this mismatch with all domains that were created not matching the primary SIP/SMTP domain I would suggest.  Additionally, if your logging your Hub in via LAN you will most probably need to bundle up some certificates as the Hub will not trust your certificate authority used for signing Front End certificates that would include domain.local SANs which Public Certificate Authorities reject.

You’ll be happy to note that Godzilla and I are now on speaking terms again. We quite regularly have catch ups via Skype with colleagues and its all smiles once again.

Change ring tone behaviour with a Sonus SBC and SIP trunk provider

I recently had an issue with calls originating from a SIP trunk provider to Skype for Business Server(s) that needed to change who supplied the ring back tone. This would have been a much simpler process with ISDN, but SIP trunks are a much more involved PSTN connection. If you’re having problems with ring back this should help provide a quick troubleshooting step to expose a problem in this area. This article specifically describes what to change in Skype for Business and Sonus 1000/2000 SBC to get the desired outcome with a SIP trunk. “Ring-Ring, Ring-Ring!“.

A notable mention is that SIP Trunk Providers are not all created equal. The call setup could differ from this example.

My aim which led to this article was to change the ringtone generation from the SBC, to be supplied by the carrier. As I hunted through the SBC capture for the call setup information, I noticed the Mediation Server sends a 183 message with SDP back towards the SIP Trunk as seen in the below;

183 with SDP

I wanted to stop this behaviour of the Skype for Business Mediation Server sending 183 Session Progress messages to the carrier during inbound call setup. As this was contributing to whom was generating the ring back in my scenario. I’ll explain…

What are we looking at here?

The highlighted capture shows a 183 Progress going back towards the carrier in the setup of the call with a SDP. We are interested in this step because it has SDP which is leading towards whom/what is going to perform the ring tone generation.

What is a 183 Message?

Wiki has me covered here.

183 Session in Progress: This response may be used to send extra information for a call which is still being set up

Versus standard 180 Ringing

180 Ringing: Destination user agent received INVITE, and is alerting user of call
Thanks Wiki! Therefor the message we are looking at above has a 183 with SDP. We know two things;
  • The call is still being setup
  • and there is still codec information being arranged.

Some important details I note about SDP

How do I know a message has Session Description Protocol (SDP) information?
Content-Type: application/sdp
I know its an audio profile equalling RTP Audio Video Profile (RTP/AVP):
m=audio 30190 RTP/AVP 8 0 97
I know some of the codecs being sent for media. We are sending standard G.711 audio codecs used in PSTN calls:
G.711 A-Law 
rtpmap:8 PCMA/8000/1
G.711 µ-Law
rtpmap:0 PCMU/8000/1

So what’s going to happen?

The default behaviour for a Sonus SBC is to allow 183 Session Progress messages (why wouldn’t it!), which leads to Early Media during the initial call setup. Simply, the sequence of these messages sent to SIP Trunk with a 183 Session Progress messages with SDP information makes the SBC decide to generate the ring back internally.

Okay, we know why its happening. How can we stop this behaviour? I want to make the carrier work for their money.

I figured I could achieve this via stopping 2 things:

  1. Disable the Early Media message from the SIP Trunk Provider to the SBC and onward
  2. Remove the 183 Session Progress messages with SDP from the Mediation Server heading back to the trunk

Disable the Early Media message from the SIP Trunk Provider passing through

On the Signalling Group that connects the carrier and the SBC. Disable Early 183.

Early 183

Remove the 183 Session Progress messages with SDP from the Mediation Server

There isn’t a way to disable this natively in Lync/SFB Server so this is why we want to do it on the SBC. We are going to manipulate packets coming from the Mediation Server back to the SBC before it gets sent to the carrier.

Under the Settings Tab > Telephony Mapping Tables > Message Translation. Create Message Translation Table

Remove SDP Translation

Key notes from above:

Incoming criteria to match:

  1. Looking for 183 Progress Messages
  2. Includes SDP information

Outgoing result:

  1. Change the Message Type to 180
  2. Remove the SDP

(If I was to leave the outgoing message type as 183 but strip the SDP portion, the call will progress with no ring back and the inbound caller will experience silence throughout this time).

Apply this Message Translation to the Call Route Table from the SIP trunk. This is what makes the translation active on all proceeding inbound calls. The resulting call setup;

180 Ringing

Ring-Ring, Ring-Ring” says the carrier.

Block Inbound/Outbound Calls on Sonus SBC 1000/2000

At Kloud we had an interesting chat amongst the UC group on how to best implement call blocking/screening on a Sonus Session Border Controller 1000/2000. We proceeded to trial various methods including a well documented ‘Action Set’ scenario, which proved to be unreliable in our implementation. It was from this we looked to a simpler method that I will share with you in this article.

The process to block a call will be to use a Call Route Type with ‘deny’ action as the destination type, rather than the standard process of the destination being a FXS, FXO or SIP signalling group. Sounds simple enough.

The high level tasks are:

  • Create a Transformation Table
  • Create a Call Route Entry
  • Assign the Transformation Table to the Call Route Entry
  • Assign the Call Route Entry to a Route Table

Create a Transformation Table
Create a Transformation Table, this will be populated with either calling or called address that you wish to block based on your scenario. I’ve created a table that will match a known calling address that is to be blocked. The basis of my table logic is if a call is matched set a value to equal 1. Once the call has finished the logic in the table sequence and the value is 1 then a mandatory match is made and the table becomes true/successful.

Update: My good friend Greig and I had a conversation about this table and we agreed that you don’t need this third line entry. I had the third line to make the call logging simple when searching for the specific string for the value 2 ‘Block’. Really I could remove it.

If a Transformation Table only contains multiple entries for a single Input Field Type (e.g. Calling Number above), and all of entries have a Match Type of Optional, then the table is true if any one of the transformations succeed.

Create a Call Route Entry
This step is where the magic happens and I will admit I have never toggled this drop down menu until this process. You can create a call route destination type with a ‘deny’, generally speaking as a voice consultant we are trying to complete calls not stop. Create a Call Route Entry that has the following specific settings:

  • Transformation Table = Block Calls (table from above step)
  • Destination Type = Deny
  • Q.850 Cause Code = 21: Call Rejected

Assign the Transformation Table to a Route Table
Assign the Transformation Table to the Route Table that the call originates from:


The logic of the transformation table is as follows;

  1. The table gets processed for an inbound call session
  2. A Calling Number (tfCallingNumber) field gets matched via regex we have assigned in a line entry
    1. IF TRUE – The output field User Value 1 (tfSGUserValue1) gets updated to the value ‘1’
  3. A mandatory entry of User Value (tfSGUserValue1) equals 1 is matched in a line entry
    1. IF TRUE – The output field User Value 2 (tfUserValue2) is now ‘Block’
  4. Table is successfully matched based on mandatory assignment with User Value 1
  5. Process the session with Route Table Entry ‘Block Calls’
  6. The session will be denied with code 21 Rejected in the session info

Below is a trace of an inbound call session using the LX logging tool (above steps highlighted below)

Line 280: com.sonus.sbc.route.libcommon DEBUG (AFSessionManagementLayer.cpp:650) - SMConnection: Received REQ: id=12:47657/32769/0 session bit=1 moredata bit=0 message=MSG_CR_ROUTE
Line 281: com.sonus.sbc.route INFO (callrouter.cpp:2199) - Handling route request.
Line 282: com.sonus.sbc.route INFO (callrouter.cpp:2278) - Using table From PSTN (2) to route call.
Line 283: com.sonus.sbc.route INFO (callrouter.cpp:2354) - Rule Block Calls (2.1(3)) being tested for selection.
Line 284: com.sonus.sbc.route DEBUG (translation.cpp:1416) - Performing OPTIONAL transformation using entry User Value 0 (9.1(3)).
Line 285: com.sonus.sbc.route DEBUG (translation.cpp:704) - Successful regex match of "tfCallingNumber" field for "(.*)" (updated "(.*)") with input of "411111111"
Line 286: com.sonus.sbc.route DEBUG (translation.cpp:749) - Regex replacement output of "tfSGUserValue1" field is "0"
Line 287: com.sonus.sbc.route DEBUG (translation.cpp:1416) - Performing OPTIONAL transformation using entry Block ID (9.2(1)).
Line 288: com.sonus.sbc.route DEBUG (translation.cpp:704) - Successful regex match of "tfCallingNumber" field for "411111111" (updated "411111111") with input of "411111111"
Line 289: com.sonus.sbc.route DEBUG (translation.cpp:749) - Regex replacement output of "tfUserValue1" field is "1"
Line 290: com.sonus.sbc.route DEBUG (translation.cpp:1416) - Performing OPTIONAL transformation using entry Block ID (9.3(2)).
Line 291: com.sonus.sbc.route DEBUG (translation.cpp:700) - Failed regex match of "tfCallingNumber" field for "881111111" (updated "881111111") with input of "411111111"
Line 292: com.sonus.sbc.route DEBUG (translation.cpp:1416) - Performing MANDATORY transformation using entry User Value 1 True (9.4(4)).
Line 293: com.sonus.sbc.route DEBUG (translation.cpp:704) - Successful regex match of "tfUserValue1" field for "1" (updated "1") with input of "1"
Line 294: com.sonus.sbc.route DEBUG (translation.cpp:749) - Regex replacement output of "tfUserValue2" field is "Block"
Line 295: com.sonus.sbc.route INFO (translation.cpp:1493) - Transformation table(Block Calls:9) is a SUCCESS
Line 296: com.sonus.sbc.route INFO (callrouter.cpp:2412) - Successful route request with entry Block Calls (2.1(3))
Line 297: com.sonus.sbc.route.libcommon DEBUG (AFSessionManagementLayer.cpp:1984) - Sending RSP: state=1 session id=12:47657/32769/0 message=MSG_CR_ROUTE_ACK msg len=557 end session=0 sessions={lvl=1}<parent>0x11000023|0x16721c-[this]0x11013650|0x12f140. Process ID 5912
Line 305: com.sonus.sbc.route.libcommon DEBUG (AFSessionManagementLayer.cpp:1016) - SMConnection (0x167208): Received INFO: session id=12:47657/0/0 message=MSG_CR_CALLREPORT end session=1, moredata=0

Job Done

This is a very simple approach to an annoyance that we all could face at some stage. I’m sure there are many other ways to implement a call scenario like this, but I do enjoy the beauty in this simplicity. By using the standard call route logic of the Sonus we haven’t introduced anything new to the call flow procedure. I’d estimate that a implementation like above would take about 10-15 minutes once you know what you would like to block.

Polycom VVX Phone – Call Transfer Options

During the pilot phase of a Skype for Business Enterprise Voice rollout it is standard practice to get some IP handsets in and do testing on functionality. Its important to try match feature sets between old and new handset functionality to make sure adoption of the new handset is simple.

How did you do it before? Here is how you do it now.

The longest conversation I have with this phase of testing is which transfer type will the business adopt as a default for all phones. There are 3 types of transfer that I like to discuss in Skype for Business;

  1. Blind Transfer – Transfer happens immediately
  2. Consultative Transfer – Transfer happens after a consult with the transferring recipient
  3. Safe Transfer – Returns the call on a blind transfer if the recipient doesn’t answer

The Polycom VVX Business Media phone range is what I prefer to deploy in organisations adopting Skype for Business. Polycom offer flexibility in how you configure the phone. This is done via in-band provisioning process built in by Polycom for a configuration file download. The configuration file allows for a default transfer type to be associated with the transfer soft and hard key in a standard call scenario. Two options are available;


Having a singular transfer type isn’t always optimal, especially when in conversations with workers that do high call volume for a public interfacing number i.e. Receptionist/Admin workers. These users quite often will give me the response when asked the question about which transfer they use in their job pre Skype for Business;

“Sometimes I like blind and other times I like consultative, it all depends on the calling party and how comfortable I feel with the requester in each call”.

This seems like a fair statement but not easily achieved with a VVX phone. I would tend towards default being blind and if the user wanted to do an ad-hoc consultative we would say to put the calling party on hold while you liased with the destination party and stich the call together after. Not perfect. Another method is to create a different configuration file for special cases where the user needed consultative as their default. Once again, not perfect.

My idea was to make soft keys on the ‘in call’ window on the phone for both blind and consultative transfer in my customized configuration file. This is achievable but I never sat down for long enough to pilot the process in its entirety. Older versions of the firmware I believe had consultative as default, during a call you had the option of transferring using the Blind method via a softkey but it wasn’t always on the first page of soft keys. Users wouldn’t always have the time or patience to go find the Blind key on the second page under the ‘more’ button.

But alas, Polycom have come to the rescue with UC 5.3.+ software now available for the VVX range that includes the simplest change in detail of the user guide that got me excited about an addition in functionality. User Guide (Page 46 or below)

To transfer a call:

  1. During a call, do one of the following
    1. Press Transfer to use the default transfer type
    2. Press and hold Transfer and select a transfer type.
  2. Dial a number or choose a contact from the call list or directory.
    1. If the transfer type is set to Blind, the call is transferred immediately.
  3. If the transfer type is set to Consultative, press Transfer after speaking with your contact.

Well there you have it, a very simple method of selecting a transfer method during a call. In some ways almost comical that I never once tried to hold down the transfer key. Now I do it by design. This is definetly something I’ve updated in my ‘how-to’ guides for end users adoption as it was the most common question I get in regards to VVX IP phones.

Federated User – Presence Unknown

Here at Kloud we have just been busy updating our Skype for Business Public Certificate before it expired. Our SAN certificate provided by GoDaddy is used on our Edge Server and Reverse Proxy for all external communication to be encrypted with TLS or HTTPS.

After updating our certificate and restarting services to make the certificate take effect, we started to get some feedback from Kloudies (Kloud Employees) of federated contacts showing up with ‘Presence Unknown’ in their contacts list. These were contacts which they had previously been communicating with prior to the certificate change. The head scratcher was that it wasn’t all federated partner domains.

Here is some of the findings and troubleshooting we performed to get to the resolution of the issue.

First thing to always test is the inbuilt PowerShell cmdlets on your server itself.

Test-CsFederatedPartner -Domain -TargetFqdn kloudedge.kloud.local

Successful domains appear with the following lines:
Target Fqdn   : kloudedge.kloud.local
Result        : Success
Latency       : 00:00:00
Error Message :
Diagnosis     :

While domains that had the issue would have the following output:
ErrorCode=1047,,Reason=Failed to complete TLS negotiation with a federated peer server,fqdn=SIP.Contoso.COM:5061,peer-type=FederatedPartner,winsock-code=10054,ip-address=xx.xx.xx.xx,winsock-info=The peer forced closure of the connection

From the above message we could see that the peer’s (being the federated partner) Access Edge server was actively closing the connection from our server.

But why?? We haven’t done anything wrong….

This can become a hard thing to troubleshoot if you don’t have access or know the SFB administrator at the partner organisation. Lucky for us this isn’t the case for at least one of our troubled SIP domains.

Investigating the Partner Edge Server we did the following:

  1. Start > Run mmc.
  2. File > Add/Remove Snap-in… > Add… > Certificates (Add) > Service Account  > Skype for Business Server Access Edge (Finish) > Close > OK.
  3. In the mmc, navigate to RtcSrv\Accepted Certificates > Certificates.
  4. Look for the certificate named “”

What we found was still a copy of the certificate that had just been expired, but no new certificate with the up to date expiration. We wanted to give this Edge Server a little helping hand and investigate why it would potentially not have added the new certificate into this store. Upon copying the new file to a location on the server and opening the certificate for viewing, we assessed the path of certificate. Bingo! The certificate path was not validated.

The server was missing the GoDaddy Intermediates that are associated with our new certificate. Upon adding the new GoDaddy intermediate certificates to the intermediate store location and restarting the Acess Edge Service to make certificate settings take effect, instant success. The new certificate was downloaded from our Kloud Edge Server into the Accepted Certificates store of this Edge Server whom we were talking with and presence was restored both ways.

So now we have made the assumption of knowing all the federated partners we associate with that don’t patch their Edge Server with Windows Update. I hope I’m not talking about you.

Edge Servers can easily be the servers that you forget to put in a patching cycle due to being in a DMZ restrict zone, also they are workgroup machines so they won’t take the default group policy settings from WSUS. But here is a prime example of how it could have negative impact on your company if you don’t. So the only way to fix the issue is to spread the word. I don’t have access to everyone. Until they read this blog I can’t chat with them online. The moral of the story;

Patch your Edge Server so they can have up to date certificate information or get left behind while the rest of the Skype for Business world keeps moving on


Skype for Business Online to On-Premises Migration

Okay guys – you’ve been told “lets move everyone back from the cloud! We need Enterprise Voice for our users” This will go against most Microsoft sales materials as we should be looking towards cloud.

If you are part of an organisation that has been birthed out of Skype for Business Online (SFBO) as part of your Office 365 subscription, it would make sense that you would have never had on-premises Lync or SFB servers in your Active Directory domain. Very little configuration is needed in SFBO and a busy administrators would have loved enabling the license SKU for SFBO for each users and then wiped their hands of it. Its just that easy, enable and forget.

The main limitation around SFBO is the need for an IP-PBX and/or PSTN connectivity. The time may have come for your organisation to leverage your Microsoft agreement even further and look to your existing technology/application catalogue and see that Skype for Business can fill the requirements of your aging PBX. This trigger point is usually when the PBX asset has reached capacity and there is a cost trade off;

  • Throw more money at the dusty old PBX box for extra expanision cards and possibly cabling to terminal
  • Spend the money to start new in the world of VOIP, but look to an existing technology that can provide this functionality (and hopefully more) before looking elsewhere

Telephones have been around for a long time, its nothing new. Picking up, making, transferring calls is all pretty standard stuff we have been doing for few decades now. If I’m going to invest money in something I should be asking for more! more! more! How do I make sure that my choice keeps my organisation staying relevant in the way it communicates for the next chapter?

Hello Skype for Business as PBX replacement.

That’s enough of ramble. You have come here to understand the process of moving users back from the cloud because there is less documented about this procedure than too the cloud.

Current Environment

  • On-premises Domain Services
  • DirSync/AADSync Server
  • Office 365 Tenant
    • Skype for Business Online SKU enabled
  • DNS for my
    • CNAME
    • CNAME


In this scenario we will look at the steps needed to specifically enable Hybrid and move users back to on-premises.

  1. Add on-premises infrastructure
  2. Connect Hybrid SFB with Office 365 and on-premises
  3. Move Enterprise Voice users back

Add On-premises Infrastructure

  • Add your Front End, Edge and Reverse Proxy Infrastructure
    1. Build the Servers as per TechNet, but leave the SIP Address’s DNS zones to not effect internal and external clients just yet
    2. All discover records should still point to Microsoft (sipdir, webdir etc)
  • Confiure your Edge and Reverse Proxy with Public Certificates
    1. Test the port authentication as best you can;
      1. Telnet to Edge Ports
      2. Test Reverse Proxy URLs
      3. Remote Connectivity Analyzer for Edge
  • Configure Edge for Federation
    1. Assign your Edge as the Federation Route in your Topology Builder
    2. Configure Edge Specific Configuration
Set-CSAccessEdgeConfiguration -AllowOutsideUsers 1 -AllowFederatedUsers 1 -UseDnsSrvRouting -EnablePartnerDiscovery $true
  • Recreate Allowed Federated Domains in On-premises
    1. If you do a get-csalloweddomain in Office 365 you may not get all the correct information specific for your tenant back to you.
      1. If you have federation with only allowed/block lists, you may need to recreate these as there is no nice way of piping the cmdlets from ‘get’ to ‘new’.
      2. Allow open federation to accommodate for all traffic is the simplist approach for migration
  • Set the Global Remote Access and Federation User Policy to Allow
Get-CsExternalAccessPolicy -Identity Global | Set-CsExternalAccessPolicy -EnableFederationAccess $True -EnableOutsideAccess $True


Connect Hybrid Skype for Business

  • Remove existing Lync/Skype for Business Hosting Rule
Get-CSHostingProvider -Identity <SFB/Lync Online> | Remove-CSHostingProvider
  • Recreate the Provider with Hybrid Specific Configuration
New-CSHostingProvider -Identity SFBOnline -ProxyFqdn "" -Enabled $true -EnabledSharedAddressSpace $true -HostsOCSUsers $true -VerificationLevel UseSourceVerification -IsLocal $false -AutodiscoverUrl
  • Update External/Public DNS Records
    1. Remember that only updating external DNS records means that your internal users can functions ‘as-is’ until your happy with the progress
      1. Edge Names (SIP Access/Web Conference/ AV  FQDNs)
      2. External Web Services FQDN
      3. Dialin FQDN
      4. Meeting FQDN
      5. LyncDiscover FQDN
      6. SRV
      7. SRV
    2. Remote users that aren’t previously authenticated could have an issue logging in at the time of the change

Test Process

Join On-premises Pilot User with Online Account

This makes your on-premises deployment aware of active directory accounts that are currently cloud enabled.

  • Run the following cmdlet in SFB Management Shell connected to on-premises servers to test a user
Enable-CsUser -Identity &lt;accountname&gt; -SipAddress "sip:<sipaddress>" -HostingProviderProxyFqdn "" -verbose
  • Synchronise AADSync/DirSync
    1. Login to Directory Sync Server
    2. Run >  Delta Import And Delta Sync on the Active Directory Connector
    3. You will see an update count that includes your object

Move a Pilot Users back

This step will actually move the user from SFB Online back to your on-premises pool with contact lists intact. This is initiated from the on-premises server and will need authentication for the Office 365 tenant to perfom the task.

  • Run the following cmdlet in Powershell connected to both on-premises and online sessions
Import-Module LyncOnlineConnector
$credential = Get-Credential
$session = New-CsOnlineSession -Credential $credential
Import-PSSession $session -AllowClobber
  • Get the Online Admin URL for your tenant
    1. Log into Office 365 Portal
    2. Check the URL presented in the address bar, will be admin0x. Where x = a letter specific for you
  • Move the User back
Move-CsUser -Identity <UPN> -Target <FE Pool Name> -Credential $cred -HostedMigrationOverrideURL

Enable All Users

If the above to Pilot Tests worked we need to scale up our migration batches. We need to mass produce the following cmdlet in SFB Management Shell connecting on-premises user accounts to the corresponding online account;

Enable-CsUser -Identity <accountname> -SipAddress "sip:&lt;sipaddress&gt;" -HostingProviderProxyFqdn "" -verbose

To do this practically I used the UPN value which I knew that would resolve to the correct users values in on-premises and Office 365 because they are synced from the source. I also could then understand the logic that the users UPN is in this case the primary SMTP/Mail value and therefor matching SIP Address for Skype for Business that I needed.

  • Get all the Office 365 users that are enabled for Skype for Business
Get-CSOnlineUser | ? {$_.SipAddress -notlike $Null} | Select SipAddress, DisplayName | Export-CSV -Path C:\temp\OnlineUsers.csv -NoTypeInformation
  1. This will give you a list of ‘real’ SFBO users that are licensed but are also registered SFB logins
  2. Review the list for deleted users that haven’t been removed properly, there SIPAddress will include GUID style login, these lines can be removed as we do not wish to migrate them.

Lets leverage this list of known online users and enable their joining in on-premises with a ForEach loop example below;

$Users = Import-Csv C:\updates\OnlineUsers.csv

ForEach($User in $Users)
$SipAddress = $user.sipaddress
$UPN = $SipAddress.replace("sip:", "")
$Enable = Enable-CsUser -Identity $UPN -SipAddress $SipAddress -HostingProviderProxyFqdn ""
  • Update Azure Active Directory of the changes by another AADSync/DirSync > Delta Import & Delta Sync
  • Update Internal DNS to point all associated SFB records to on-premises Skype for Business Server(s)
    1. SRV
  • Add Additional A Records
    3. Pool Name
    4. SFB Web Service URL Names
    5. Admin URL

Visual Indication of Success

Log into your on-premises SFB Admin Control Panel and run a blank user search to discover all users. Noticed the ‘Homed’ field should say ‘SFBOnline’ 

Move All Users

Leveraging the same list of users, run the move cmdlet like the example;

ForEach($User in $Users)

$Displname = $user.displayname
$SipAddress = $user.sipaddress
$UPN = $SipAddress.replace("sip:", "")
$Move = Move-CsUser -Identity $UPN -Target &amp;amp;amp;amp;amp;amp;lt;FE Pool Name&amp;amp;amp;amp;amp;amp;gt; -Credential $credential -HostedMigrationOverrideURL -Confirm:$false
if($Move -eq $False)
Write-host "User $SipAddress didn't move!!"


To get visual status while you move all the users, log into your Office 365 Skype for Business Administration Portal and view the details. Continually refresh the page to see the value for “users synced and homed online” go down as each user becomes enabled on-premises.





Log into your on-premises SFB Admin Control Panel and run a blank user search with a additional filter for Homed or Registrar Pool / is equal to / <registrar server name>.

Client Experience

The client should be unknowning of your changes being made in Office 365 and on-premises until you perform the move-csuser request for their account. During this period a redirect message will be sent to the client with a new registrar server FQDN and a automated logout and login will happen. If the user doesn’t have their client in the forground of their desktop, then this will happen silently in the background. The redirect in my move request had the users logged out and back in within about 1-2 seconds.

EnableSkypeUI Where Art Thou?

Are you missing the EnableSkypeUI from Lync Management Shell in Lync Server 2013?

If you have deployed a Skype for Business (S4B) client into your Lync Server 2013 environment you may see the following error upon login:

Skype warning on Start

There are plenty of articles about how to switch the client via Office365 Powershell, Lync Management Shell or the Registry, but if you’re scratching your head on how to get the new parameter “CSClientPolicy” here are some steps that may have been missed.

The new client software that supports both the Lync 2013 and S4B user interface (UI) modes does a quick check for which server version you are running and then remediates the UI to the current version unless the registrar server responsed with the following attribute configured in the user’s CSClientPolicy:

EnableSkypeUI – true/false

  • True – Enables S4B UI
  • False – Enables Lync UI

If you don’t find the EnableSkypeUI attribute in Get-CsClientPolicy you will need to patch your servers with the latest cumulative update. The trick to this is if you’re automatically patching the CU updates to Lync Server you must make sure that you also manually patch the database. There is the possibility that you may have forgotten that the database needs a update and it is always a good idea to revisit. We must do this to make sure that not only the Front End Servers are up-to-date but also the Backend SQL database schemas have been updated to include the new setting(s).

Get the latest patches for the servers:

To run the Installer, run the following command on each Front End:


Apply all the patches.

Apply the back-end database updates (SE Pool shown below):

Install-CsDatabase -ConfiguredDatabases –SqlServerFqdn <FQDN> -Verbose

Run Lync Management Shell:

Get-CsClientPolicy | select Enable* 

EnableSkypeUI should now be visible, but will be set to $null.

The behaviour of the change when set to $true is relatively smooth. The Lync client will show a message similar to the grab at the start of this post

Restart Lync to see new Skype UI

The toolbar icon will represent the current client mode also:

Old Lync Icon on Windows Taskbar

The client will completely exit and restart in Skype for Business mode:

Skype for Business Splash Screen

Also the relevent Taskbar icon will be updated for continuity:

Skype Icon on Windows Taskbar