Enable-CsTopology : Error accessing folder \\sfbshare

I have made some changes to my Skype for Business topology and I finished that as usual with the cmdlet “Enable-CsTopology”.

However, I got like 51 errors all stating :

Enable-CsTopology : Error accessing folder
\\sfb-fe.contoso.com\sfbshare\1-ApplicationServer-1\AppServerFiles\CPS.
At line:1 char:1
+ Enable-CsTopology
+~~~~~~~~~~~~~~~~~~
+ CategoryInfo : Invalid Data: (:SourceCollection) [Enable-CsTopology], DeploymentException
+ FullyQualifiedErrorId : InvalidFolder,Microsoft.Rtc.Management.Deployment.ActivateTopologyCmdlet
Enable-CsTopology : Error accessing folder \\sfb-fe.contoso.com\sfbshare\1-ApplicationServer-1\AppServerFiles\Rgs.
At line:1 char:1
+ Enable-CsTopology
+~~~~~~~~~~~~~~~~~~
+ CategoryInfo : Invalid Data: (:SourceCollection) [Enable-CsTopology], DeploymentException
+ FullyQualifiedErrorId : InvalidFolder,Microsoft.Rtc.Management.Deployment.ActivateTopologyCmdlet
Enable-CsTopology : Error accessing folder \\sfb-fe.contoso.com\sfbshare\1-ApplicationServer-1\AppServerFiles\WinFabTraceFiles.
At line:1 char:1

lync

The errors clearly mention an access to lyncshare folder error. I tried to actually enter the share folder through its FQDN, and I browsed in Windows Explorer \\sfb-fe.contoso.com\sfbshare and SURPRISE!! I was denied.

I browsed again the Lyncshare but this time through its IP address \\@IP-ADDRESS\sfbshare and it works! So, I understood that it was a DNS related issue.

I opened a cmd shell and did a simple ping sfb-fe.contoso.com and I got an IPv6 response!

I disabled IPv6 on the network card like that :ipv6

and did an ipconfig /flushdns on cmd.

After these two actions, I was able to browse the SFB Share through its FQDN and finally the share folder is accessible and the Enable-CsTopology worked successfully.

It’s really surprising because the SFB was up and running in production. I don’t want caused the Enable-CsTopology where no recent changes happened.

Integrating Cisco Meeting Server with Lync/Skype for Business

I have implemented this week multiparty conferencing through the new Cisco’s CMS conferencing product. CMS enables Lync and Cisco users to participate in the same conference with a seamless behavior between Lync and Cisco experience.

The CMS is excellent for organizations where both Lync and Cisco UC deployments are used. (yes, Cisco is best in Telephony, yes Lync is best in Chat & IM, and yes opinions are shared for video/webconferencing)

The configuration is pretty straightforward. I’m really surprised with the ease of the configuration in CMS.

I will not detail how to integrate CMS with CUCM. A prerequisite of the following is that Cisco endpoints eg. Jabber and/or DX endpoints are able to connect to the same Space.

Note that the word “Space” in Cisco meeting Server is actually the equivalent of the Collaboration Meeting Room in Cisco Conductor.

The configuration steps on Lync/SfB Front-End are detailed in the CMS deployment guide Appendix C.

So basically, you need a choose domain for CMS  which needs to be different than the Lync domain. (for example, if your Lync deployment is contoso.com , you may choose for example the domain cms.contoso.com to route calls from Lync to CMS). This is because Lync needs to differentiate “Lync internal” calls (user@contoso.com) from “Lync external” calls (room@cms.contoso.com). You may even choose a completely different domain like “contoso2.com”, not only a different subdomain.

Here are the steps :

1- Download the Root CA certificate that signed the CMS certificate and import it to each Lync Front-End server. Put it in the “Trusted Root Certificate Authorities” folder. The Root CA certificate should be a .cer or .crt or whatever certificate file extension.

Importing the Root CA certificate that signed Lync Front-Ends to CMS is recommended however not required since CMS certificate verification is disabled by default.

2- Open Lync Server Management Shell to create the “Trunk” between Lync and CMS. The “Trunk” with CMS will be of type “Trusted Application Pool”; as far as Lync guys are concerned. Type the following cmdlets :

New-CsTrustedApplicationPool -Identity cms.contoso.com -ComputerFqdn cms.contoso.com-Registrar sfb-pool.contoso.com -site 1 -RequiresReplication $false -ThrottleAsServer $true -TreatAsAuthenticated $true

New-CsTrustedApplication -ApplicationId meetingserver-application -TrustedApplicationPoolFqdn cms.contoso.com -Port 5061

$x=New-CsStaticRoute -TLSRoute -Destination “cms.contoso.com” -MatchUri “cms.contoso.com” -Port 5061 – UseDefaultCertificate $true

Set-CsStaticRoutingConfiguration -Identity global -Route @{Add=$x}

and Finally : Enable-CsTopology

3- That’s it ! From a Lync client call “room@cms.contoso.com” and you should be in the virtual room. Don’t forget to open your webcam. Seems that Lync don’t negociate inbound Video until you actually open your webcam and trigger the outbound Video negociation.

4- You may face a problem where the Lync call to “room@cms.contoso.com” window appears and then disappears suddenly and the call gets disconnected.
I troubleshooted the issue in the CMS

2017-01-25 16:17:47.805 Info call 25: recognised as Lync
2017-01-25 16:17:47.805 Info call 25: incoming encrypted SIP call from “sip:lyncuser@contoso.com” to local URI “sip:room@cms.contoso.com” (Lync)
2017-01-25 16:17:47.817 Info conference “Test”: unencrypted call legs now present
2017-01-25 16:17:47.922 Info participant “lyncuser@contoso.com” joined space 32c459e9-fb89-4b5f-96d9-73aab7e5c7f4 (Test)
2017-01-25 16:17:47.962 Info call 25: ending; remote SIP teardown; ICE negotiation in process – connected for 0:00
2017-01-25 16:17:47.962 Info participant “lyncuser@contoso.com” left space 32c459e9-fb89-4b5f-96d9-73aab7e5c7f4 (Test)

A detailed call trace on CMS will show a SIP BYE message with the cause :
ms-client-diagnostics: 52001;reason=”Client side general processing error.”;UserType=”Callee”;MediaType=”audio”

2017-01-25 16:18:50.797 Info SIP trace: connection 31: incoming SIP TLS data from 10.210.30.9:59210 to 10.210.30.5:5061, size 699:
2017-01-25 16:18:50.797 Info SIP trace: BYE sip:room@cms.contoso.com;transport=tls SIP/2.0
2017-01-25 16:18:50.797 Info SIP trace: Via: SIP/2.0/TLS 10.210.30.9:59210;branch=z9hG4bKDEEFB2EF.FF22BB7957D3B46E;branched=FALSE
2017-01-25 16:18:50.797 Info SIP trace: Max-Forwards: 69
2017-01-25 16:18:50.797 Info SIP trace: Via: SIP/2.0/TLS 172.30.22.241:6174;ms-received-port=6174;ms-received-cid=E5400
2017-01-25 16:18:50.797 Info SIP trace: From: <sip:lyncuser@contoso.com>;tag=d8804dbf7f;epid=eedfaef46a
2017-01-25 16:18:50.797 Info SIP trace: To: “Test” <sip:7000@cms.contoso.com>;tag=a1ed2fe26aae6b2b
2017-01-25 16:18:50.798 Info SIP trace: Call-ID: 3238de7a9d0547978d0a00d24623c4cb
2017-01-25 16:18:50.798 Info SIP trace: CSeq: 2 BYE
2017-01-25 16:18:50.798 Info SIP trace: User-Agent: UCCAPI/15.0.4893.1000 OC/15.0.4893.1000 (Skype for Business)
2017-01-25 16:18:50.798 Info SIP trace: ms-client-diagnostics: 52001;reason=”Client side general processing error.”;UserType=”Callee”;MediaType=”audio”
2017-01-25 16:18:50.798 Info SIP trace: Content-Length: 0
2017-01-25 16:18:50.798 Info SIP trace: ms-routing-phase: from-uri-routing-done

The problem was that, by default, the “SIP Media Encryption” parameter on CMS (menu Configuration > Call Settings) was set to “disabled”. Since Lync requires encryption you may turn it to “allowed” and everything will work as a charm!

One last thing, the Lync client can also give you the presence status of the room. It will show Ready if nobody is in the Room and “In a call” if a meeting is in progress.

Server Side Conversation History with SfB on premise and Exchange Online

Yes it works also in a hybrid scenario.

These two days I struggled to implement the new (well it dates from 2015) Server Side Conversation History for a customer who has a Skype for Business 2015 on-site (from Enterprise Voice and Telephony) and Exchange Online through Office 365.

So, I used some useful blog posts from Cloud Exchangers for the whole process understanding of Server Side Conversation History. I understood that for the Server Side Conversation History to work the cmdlet

Test-CsExStorageConnectivity –SipUri user@contoso.com -Verbose

has to pass successfully.

This command means that Oauth (Server to Server authentication) between SfB on prem and Exchange online should be OK.

So again, another blog post from Cloud Exchangers about OAuth is very useful to implement this.

However, at the end of the configuration, when the Test-CsExStorageConnectivity cmdlet it throws an error :

VERBOSE: Successfully opened a connection to storage service at localhost using binding: NetNamedPipe.
VERBOSE: Create message.
VERBOSE: Execute Exchange Storage Command.
VERBOSE: Processing web storage response for ExCreateItem Failure., result=ErrorUserSmtpMissing, activityId=2a173b88-ecb5-43ca-a0be-09f3fdb7bb2e, reason=StoreException: code=ErrorUserSmtpMissing, reason=Found user sipUri=[sip:user@contoso.com], but SmtpAddress is null/empty, ensure mailbox is enabled.
at
Microsoft.Rtc.Internal.Storage.Store.StoreConnectionManager.LookupUserDetails(StoreContext ctx, String sipUri, Guid& tenantId, String& smtpAddress, String&userSid,String& userUpn)
at
Microsoft.Rtc.Internal.Storage.Store.StoreConnectionManager.GetExchangeContext(StoreContext ctx, String sipUri)
at
Microsoft.Rtc.Internal.Storage.Store.StoreConnectionManager.GetExchangeClientProxy(StoreContext ctx, String sipUri, CacheMode cacheMode)
at
Microsoft.Rtc.Internal.Storage.Adaptor.ExStoreAdaptor.InternalCreateItem(StoreContext ctx, String sipAddress, CreateItemType createItem, Boolean autoCreateParentFolder, StoreAsyncResult`1 asyncResult, Boolean reAuthorize)
at
Microsoft.Rtc.Internal.Storage.Adaptor.ExStoreAdaptor.ExchangeCreateItem(StoreContext ctx, ExStoreRequest exStoreRequest, StoreAsyncResult`1 asyncResult)
at
Microsoft.Rtc.Internal.Storage.Adaptor.ExStoreAdaptor.BeginDispatchCommand(StoreContext ctx, StoreRequest request, AsyncCallback asyncCallback, Object state)
at
Microsoft.Rtc.Internal.Storage.Api.StorageService.BeginExecuteCommandInternal(Guid adapterId, StoreRequest request, AsyncCallback asyncCallback, Object state,
Boolean isAuthenticated)
.
VERBOSE: Activity tracing:
2016/10/19 11:57:48.179 Lookup user details, sipUri=sip:user@contoso.com, smtpAddress=, sid=, upn=user@contoso.com,
tenantId=00000000-0000-0000-0000-000000000000
VERBOSE: Unhandled response Microsoft.Rtc.Internal.Storage.StoreResponse. VERBOSE: Is command successful: False.
Test failed.

 

I double checked that the password for the User is the same between local Active Directory and Office 365. But I had no idea why am I receiving “SmtpAddress is null/empty, ensure mailbox is enabled” where the user has his mailbox fully activated and working on Exchange Online. (Remark : I have not used Dirsync, I just made sure that the password and SIP URI/EMAIL just match, I thought for a time not running Dirsync may be the problem but no… i worked without it, just read to the end)

I was desperate, especially when I read this topic on Microsoft Answers Community when somebody said it ain’t work with a such hybrid scenario.

Today, I checked another SfB deployment I have done for another customer but with Exchange on premise. I remarked that on Active Directory (open ADSI Edit), the ProxyAddresses field contains two entries which are “sip:user@contoso.com” and “smtp:user@contoso.com”.

I checked back to our problematic hybrid deployment, I found that the field ProxyAddresses contains ONLY “sip:user@contoso.com” but none smtp entry. It’s quite logic since we don’t have an Exchange On-Premise, we only have Exchange Online. And as I understood it’s while activating the user’s mailbox on Exchange that the SMTP entry is added to the ProxyAddresses field of the AD User.

So, you have understood everything !! What I have done is to manually add the SMTP field to the ProxyAddresses. Just open Powershell on Active Directory server and type this :

Set-ADUser -Identity your_user -Add @{ProxyAddresses=”SMTP:user@contoso.com”

And Guess what ? Got back to Skype for Business Management Shell to relaunch the Test-CsExStorageConnectivity cmdlet again and it showed “Test passed” ! It was because of the missing SMTP address in the ProxyAddresses field of the user located on Active Directory.

And Guess what again ? I just closed, removed all the cache, then opened Skype for Business on my Android and all the Conversation History is loaded ! IT WORKED!!

I have done the same procedure for another user having SfB on iPhone and it worked!

So the point is that integrating SfB on prem and Exchange online may have working from the beginning if we have, for example, an Hybrid Exchange shared between on premise and online. Because the Exchange on-prem should have already populated that SMTP entry in the ProxyAddresses field. But here we were on PURE Skype for Business on prem and PURE Exchange on Cloud.

And finally, the hybrid scenario of SfB on-prem with Exchange Online DO support Server Side Conversation History, not as it’s said in some forums.
I have a proof! I have a customer running Server Side Conversation History flawlessly with a such deployment scenario. Don’t be mistaken.