Wednesday, 7 May 2014

Microsoft BI: PowerView Data Source Authentication - Debugging Security Issues

When opening a BISM connection file in SharePoint 2013 – assuming you've installed Reporting Services in SharePoint Integrated mode and the Reporting Services add-in for SharePoint – PowerView fires up automatically in the browser and you’re presented with the data field list to start building your report.

On this particular occasion, in PowerView, when we went to add a field to the visualisation, we were presented with this:
PowerViewError
The error is far from intuitive: “Cannot create a connection to data source ‘EntityDataSource’". After a little digging around, I fathomed out that this had something to do with authentication through to the data source.
I should mention at this point that we had configured an Execution Account (Central Admin -> Manage Service Applications -> SSRS Svc Application -> Execution Account) for the purpose of testing unattended data refresh and report generation and that the BI Semantic Model (.bism) connector was configured to connect to a SQL Server Analysis Services tabular instance, hosted on a separate SQL Server.
More information about the Execution account here: http://technet.microsoft.com/en-us/library/ms156302.aspx (Native Mode documentation)

Investigating why - a look at the Authentication process flow

In order to understand why we were seeing the error, I set about documenting the authentication and authorisation process through to the data source:
  • When a user navigates to a SharePoint site, that person is making an anonymous request for a SharePoint page and SharePoint requests credentials from the user.
  • Once credentials have been submitted, SharePoint will seek to validate those credentials against Active Directory. If successful, an NT token is generated and sent back to SharePoint.
  • Once validated, SharePoint will query security group membership of the user and create a Claims Based security token using the Security Token Service (STS).
  • An authorisation code is generated and sent to the user’s client computer, if the user is authorised to access the page/report, through analysis of the claims, SharePoint will send the page/report.
  • The authorisation code is then used for further requests to SharePoint.
Note: In the event of a user browsing to SharePoint with Internet Explorer, domain credentials may be sent automatically and further validated by Active Directory.
The authentication process flow can be a lot more complicated than that but that’s not really within the scope of this post. Full details on the client authentication flow can be found here: http://technet.microsoft.com/en-us/library/cc262350.aspx

All right, so we’re authenticated up to and including PowerView. What happens next?

When a user opens up the BISM connector in his/her browser, the user is authenticated and authorised to view the PowerView interface, following the process detailed above. But that’s only the PowerView interface. What about the connection through to the data?
Now remember, PowerView is a Reporting Services component. Ultimately, when Reporting Services is connecting to a data source (in this case SQL Server Analysis Services Tabular mode), it must present some credentials for authentication or some form of user authorisation.

What’re the options for Authenticating?

Whether Kerberos Delegation is in place or not, the options for specifying Reporting Services data connection credentials are:
  • Prompt the user for credentials
  • Store credentials (e.g. Secure Store Service)
  • Windows Integrated security
  • Use no credentials
If no credentials are used, then the report will run in the context of the account that is set to run the Application Pool that hosts the Reporting Services Web Services. In addition, provided the account running the Application Pool has Administrator rights on the data model, it will then proceed to use the EffectiveUserName parameter to pass the name of a Windows Domain account in order for Analysis Services to impersonate that user.

Our Authentication Scenario

On this occasion, I’d mentioned already that we had specified an Execution Account and the documentation for the Execution account states that the Execution account is used to… “Send connection requests over the network for reports that use database authentication, or connect to external report data sources that do not require or use authentication. For more information, see Specify Credential and Connection Information for Report Data Sources in SQL Server Books Online.”
When an Execution Account is used to authenticate against a Tabular instance of Analysis Services, provided it has administrative privileges, it will also utilise the EffectiveUserName parameter.
We made sure that the Execution Account had access to the data source, but we were still receiving the error in PowerView.

So what’s the problem and how do we fix it?

Well… Before it can query the SQL Server, the Execution Account must convert its claims into an NTLM Windows Token. This is so that SQL Server will understand who is trying to gain access to the data (SQL Server does not understand claims). In order to do that, it must call the C2WTS (Claims to Windows Token Service).
The C2WTS can be found in C:\Program Files\Windows Identity Foundation\v3.5\ and has a .config file (c2wtshost.exe.config) that contains a section specifying who is permitted to call the service.
<allowedCallers>
   <clear />
   <add value="WSS_WPG" />
</allowedCallers>
In this  case, only the group SP_WPG was permitted to call the C2WTS.
In most cases, SharePoint Application Pool accounts are automatically added to the SP_WPG group.
Why that’s important? Well, it means that only members of the WSS_WPG group may call the Claims to Windows Token Service.

Aha! So how to solve?

Well, there are a couple of possibilities here:
  • Add the Unattended Execution Account to the WSS_WPG group
  • Add the Unattended Execution Account to the Claims to Windows Token Service .config file.
  • …Or configure the Execution Account to be a user that is already a member of the WSS_WPG
If you consider the privileges granted to the WSS_WPG group (http://technet.microsoft.com/en-us/library/cc678863(v=office.15).aspx), the preferred approach in this case is to add the Unattended Execution Account to the c2wtshost.exe.config file, granting the minimum privileges required for the PowerView report to run using the Execution Account.
Additional Information
Technet documentation for the Execution Account -
http://technet.microsoft.com/en-us/library/ms181156.aspx
TechNet page for the Unattended Execution Account -
http://technet.microsoft.com/en-us/library/ms156302.aspx

Wednesday, 2 April 2014

PowerView Issues following SQL 2012 SP1 CU9

Not so long ago, I helped to build a SharePoint 2013 farm for some testing and more recently, we (some colleagues and I) started to plan how we'd upgrade to SharePoint 2013 SP1 and SQL Server 2012 SP1 CU9.

The farm consists of two servers:
  1. server01 - SharePoint 2013 Web Front End and Application Server 
  2. server02 - SQL Server 2012, hosts config and content databases; other services include Database Services, SSAS, SSAS Tabluar etc. 
Unfortunately I didn't have the time to commit to installing the updates myself, but here's roughly what happened, according to the install log:
  1. server01
    1. SharePoint 2013 SP1 was installed
    2. Some post update cleanup tasks on server01; Disk cleanup, log trimming etc.
    3. Reporting Services Add-In for SharePoint installed (2012_SP1_RSShrPnt_CU9_2931078_11_0_3412_x64; rsSharePoint.msi) 
  2. server02
    1. SQL Server 2012 SP1 CU9 installed (SQLServer2012_SP1_CU9_2931078_11_0_3412_x64)
SQL Server 2012 SP1 CU9: http://support.microsoft.com/hotfix/KBHotfix.aspx?kbnum=2931078&kbln=en-us

Once the updates were applied, a colleague committed to some testing. We were looking to be sure that some of the more complex Business Intelligence architectural elements were still operating as we'd expect them to.

That was not the case:
  • PowerView data retrieval failed
  • PowerPivot rendering failed
  • PowerPivot / PowerView previews were not working in the Carousel or Gallery mode
In order to determine what the issue was, I set about tackling these one by one - divide and
conquer style - starting with the PowerView data retrieval.

The Issue

In a document library, there's a .bism file which has been configured to connect to the AdventureWorks tabular database on an instance of Analysis Services (SSAS) on server02. When you click on the .bism file, a PowerView canvas opens and allows navigation of the data model. That works fine.

What doesn't work fine is attempting to add dimension columns to the canvas. This error would appear:
Full details of the error:

System.Exception: Error: Invalid token in RPDS stream. StringTable token: 0x12.
at Microsoft.ReportingServices.Rendering.RPDSProcessing.RPLReader.ReadStringTable(Int64 offset, RPLContext context) at Microsoft.ReportingServices.Rendering.RPDSProcessing.RPLReader.ReadVersionedReport(RPLReport report, RPLContext context)
at Microsoft.ReportingServices.Rendering.RPDSProcessing.RPLReader.ReadReport(RPLReport report, RPLContext context) at Microsoft.ReportingServices.Rendering.RPDSProcessing.RPLReport..ctor(BinaryReader reader) at Microsoft.Reporting.AdHoc.DataManagement.Internal.DataManager.PopulateRimWithRplData(Stream stream, HashSet`1 itemsToNotParse) at Microsoft.Reporting.AdHoc.DataManagement.Internal.DataManager.HandleRenderEditResponse(IAsyncEnumeratorCallback aec)


Investigating

When trying to figure out what was wrong, I did the usual:
  • Check Event Logs - Nothing unusual here. IIS WAMREG Local Activation issue showed up. I fixed this to eliminate there being any possibility of it having an impact on this situation. (guide: http://www.wictorwilen.se/Post/Fix-the-SharePoint-DCOM-10016-error-on-Windows-Server-2008-R2.aspx) 
  • Checking of SharePoint ULS logs - SharePoint appeared to be calling the Reporting Services endpoint just fine. Although there was an exception at the time of data retrieval:

    Error occurred while canceling the command for DataSet 'Tablix1DataSet'. Details: System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.AnalysisServices.AdomdClient.XmlaClient.Connect(ConnectionInfo connectionInfo, Boolean beginSession) at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Connect(Boolean toIXMLA) at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Microsoft.AnalysisServices.AdomdClient.AdomdConnection.IXmlaClientProviderEx.Connect() at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.CancelCommand(AdomdConnection originalConnection) at Microsoft.ReportingServices.DataExtensions.CommandWrapper.Cancel() at Microsoft.ReportingServices.Diagnostics.DataExtensionConnectionBase.HandleImpersonation(IProcessingDataSource dataSource, DataSourceInfo dataSourceInfo, String datasetName, IDbConnection connection, Action afterImpersonationAction) at Microsoft.ReportingServices.ReportProcessing.CommandWrappedForCancel.Cancel() at Microsoft.ReportingServices.OnDemandProcessing.RuntimeDataSet.CancelCommand() bb43839c-cec4-50c6-4146-1d1167b52b19

    As it was different to the original issue, I noted it down and progressed with the original error. 
  • Run SQL Profiler - I captured the communication between PowerView and the SQL Server SSAS Tabular instance. I even copied the query and went and executed it separately to be sure there was no issue. Again, all fine:
  • Further head scratching...

So what next, what could I be missing?

After some more looking around and searching online, it got me thinking about whether all of the SQL Server 2012 Shared Components on the SharePoint server were updated or not.

Then a light-bulb moment: didn't the installation report say that that rsSharePoint.msi add in was installed/updated on the SharePoint server? Sure... But what about the other SQL Server Shared Components?

Sure enough, when I ran the SQL Server 2012 SP1 CU9 update package on the SharePoint server, it reported that the 'Upgrade Status' of all of the components was 'Not Installed'.

Bingo!

I noted down the patch level, hit next a few times and let the update package do it's thing.

Once complete, I ran the package again and this time the 'Upgrade Status' reported 'Installed' for the PowerPivot and the Shared Features. The Patch Level had also changed from 11.1.3128.0 to 11.1.3412.0.
I also went and tested the issues that we'd previously experienced - most had been resolved. One or two were still present and waiting on timer jobs to execute in order to fix.

Why did you run the SQL Server 2012 SP1 CU9 update on a SharePoint server?

It's very simple: there are SQL Server Shared Features that must be upgraded too. It's not enough to install only the Reporting Services Add-In for SharePoint.

In short, in this CU9 Scenario, SQL Server patching that should be applied to SharePoint 2013 is as follows:
  • SP Web Front Ends
    • 2012_SPx_RSShrPnt_CUxx_KBxxxxx_11_00_xxxx_arch
    • Applies only to WFE Servers that wish to integrate with Reporting Services (adds pages, features and content types) 
  • SP App Servers
    • SQLServer2012_SPx_CUxx_kbxxxxxx_11_00_xxxx_Arch
    • Applies only to servers running PowerPivot for SharePoint and any additional Shareds Features such as Reporting Services in SharePoint Mode 
  • SP Web Front End & App Server
    • Install/update all that would apply; in this case, both of the above packages applied.
  • SQL Server - SQL Server Software Update Package
    • SQLServer2012_SPx_CUxx_kbxxxxxx_11_00_xxxx_Arch
    • ...and any other additional CU update package that applies to the services you have installed.
SQL Server Package Naming Convention: http://support.microsoft.com/kb/822499

The message here is simple.... The landscape has become rather complex, what with the many interfaces between SharePoint and SQL Server now. So make sure you're updating all of the SQL Server Shared Features as well as core SQL Services!

Thursday, 20 March 2014

Take a photograph, make it searchable

The digital workplace has had the ability to photograph a Whiteboard for some time, whether for personal notes or to share with others. There are also mobile apps dedicated to this - even Google Drive has a 'Scan' feature with OCR text recognition, allowing the text to be indexed and thus discoverable.

Now there's something from Microsoft. It's called Office Lens. Though unfortunately only in the Windows Phone Store at the moment. Let's hope they release also an Android and iOS version.

http://blogs.office.com/2014/03/17/office-lens-a-onenote-scanner-for-your-pocket/

Wednesday, 27 March 2013

SharePoint Configuration Guidance for 21 CFR Part 11 Compliance


In April 2012, Microsoft published a White Paper titled SharePoint Configuration Guidance for 21 CFR Part 11 Compliance – I urge any SharePoint person involved in with Computer Systems Validation (CSV) subject to read it.

It’s rudimentary and unlikely that you will use exactly the use cases mentioned, but the concepts are there. It mentions one or two server technologies which may not be available in tightly governed organisations but I think that the real value is where it goes on to detail what can be done with Microsoft Office 2010 and SharePoint 2010 out-of-the-box.
Whether you agree or disagree, it then goes on to explain how exactly the Office clients and the SharePoint server platform meet aspects of 21 CFR Part 11 Compliance.
Direct link to the white paper: http://download.microsoft.com/download/9/A/A/9AA9CACF-B414-466B-BBED-86507D1D24FF/SharePoint-Configuration-Guidance-for-21-CFR-Part-11-Compliance.pdf

Wednesday, 4 July 2012

SharePoint ECMA libs in non-master page

If you have a SharePoint .aspx page that has no master page content or containers and you want to include the SharePoint ECMA client object model libs, SharePoint is very particular about how you do that.

As we know, including the libraries is as simple as including the following line of markup:

<SharePoint:ScriptLink runat="server" ID="sl" Name="SP.js" OnDemand="false" Localizable="false" />

Note: the OnDemand attribute is set to false here to ensure that the script files are loaded immediately and so that we don't have to over-complicate with ExecuteOrDelayUntilScriptLoaded()

The key thing to remember with this piece of markup is that it MUST appear after the form element. So it will look a little like this:

<form id="form1" runat="server">
<SharePoint:ScriptLink runat="server" ID="sl" Name="SP.js" OnDemand="false" Localizable="false" />



I had originally tried to put this in the <head> ... </head> element and was left head-scratching as to why it failed to include the scripts.

Friday, 30 March 2012

Configuring SQL Server Denali Reporting Services SharePoint 2010Integration

Great guide pointing out that if you should happen to install SQL Server Reporting Services 2012 before installing SharePoint, you must then let SharePoint 2010 know it's there and install the service.

http://denglishbi.wordpress.com/2011/07/22/configuring-sql-server-denali-reporting-services-sharepoint-2010-integration/

Thanks Dan!

Friday, 14 January 2011

XSLTListViewWebPart: Using CAML Query Parameters


After much searching around followed by a fair bit of trial and error, I figured out how to make use of Data View Parameters in a CAML Query in an XSLTListViewWebPart. Bear in mind I am configuring this using SharePoint designer.
So I have a list web part on a page, I open up that page using SharePoint Designer 2010 and begin editing under the hood. Once you've added a Data View Parameter you're then able to embed it as a parameter into your CAML query like so (Parameters in Bold):

<Query>
     <OrderBy> … </OrderBy>
     <Where>
     <Contains>
           <FieldRef Name="FileRef" />
           <Value Type="Text">{year}/{month}</Value>
</Contains>
</Where>
</Query>

Despite being so easy to implement, not once did I find it documented anywhere. I've labelled this post as I would have searched for it in the hope it helps out others looking for the same thing.

Monday, 10 January 2011

DataSourceID is either missing or set to an empty string

When fiddling around with the CoreResultsWebPart in SharePoint designer, or any web part for that matter, it’s easy to make mistakes in the markup.

However, more specifically, when you make a mistake in the markup of the CoreResultsWebPart it will always give the error DataSourceID is either missing or set to an empty string:

image

So of course, the first thing you do after seeing this is check your data source. I dragged another web part onto the page and compared the configuration with the one I’d been playing with in SPD. No difference – odd.

It was only through looking through the web part code that I noticed I had not closed a <div> tag that I’d put in for display of an image. I added the closing div tag </div> and voila! The web part no longer presented me with an error.

Having search around for instances where people were having the same or similar problem, somebody had suggested that you get this generic error no matter what’s wrong with your CoreResultsWebPart. So if you see the error and you believe the data source is intact, don’t be too alarmed – check your Web Part markup.

Tuesday, 14 September 2010

Connecting To SSAS Remotely Using Excel

If you plan to connect to SQL Server Analysis Services (SSAS) over the network using Excel, and your server uses Windows Firewall for protection, then you’re going to need to know how to open up Windows Firewall in order allow the connection.

Here’s how: http://msdn.microsoft.com/en-us/library/ms174937.aspx

If you try and connect without allowing such connections through the firewall, you will repeatedly get a message saying something along the lines of:

image 

If you’ve opened up the firewall and you still see this error then I’d suggest checking your installed versions of MS OLE DB, MDAC and MSXML.

Thursday, 12 August 2010

SQL Server 2008 R2 Reporting Services Add-in for Microsoft SharePoint Technologies 2010 (and the trouble it causes)


Recently I had to migrate a site collection on a development server onto a pilot server for a client. PowerShell was used to do the following:

Source Server (Development)

  • Back up the site collection using Backup-SPSite
Destination Server (Pilot)

  • Backup the existing Site Collection using Backup-SPSite
  • Delete the old Site Collection using Remove-SPSite
  • Create a new Site Collection as a container (no template) using Create-SPSite
  • Restore the Site Collection from the Source server using Restore-SPSite
The site collection contained two Site Templates in the form of Solutions (.wsp files, stored in the Site Collection Solutions gallery).

The Issue

Whenever I attempted to create a new site based on either of these templates, I was presented with an error stating that there was a missing feature dependency and gave the ID of the missing feature:


[trying to find my screenshot of this – I appear to have misplaced it]


First thing's first, what feature is that GUID referring to? I used the command Get-SPFeature | out-file C:\FeatureList.txt on both the Development and the Pilot server to get a full list of the features. Sure enough, the Development server had the feature and the Pilot server did not. Though more interestingly, the feature in question here is the 'Report Server' feature. With a little more investigation it became clear that the Development server had the 'SQL Server 2008 R2 Reporting Services Add-in for Microsoft SharePoint Technologies 2010' installed whereas the Pilot server did not.


Intriguing… Although I have not explicitly used any element of report server in my Site Collection – more to the point, in my Site Templates – SharePoint 2010 was failing to create a new site due to this feature not being present. What's even more baffling is that if there's such a deep rooted dependency on this feature, why did SharePoint 2010 allow me to restore the site collection in the first place?

Plan of Attack

Two possible options here; Regress the development environment in an attempt to re-migrate the site, minus feature dependency. Also, install the 'SQL Server 2008 R2 Reporting Services Add-in for Microsoft SharePoint Technologies 2010' on the Pilot server. I decided to run both in parallel.

Regression

Having uninstalled the 'SQL Server 2008 R2 Reporting Services Add-in for Microsoft SharePoint Technologies 2010' on the Development server, I discovered that it had left behind 3 Report Server content types that appeared to have lost their names i.e. in a zombie state:





When I tried to delete them I was presented with the error show in the screenshot below:





I could have probably gotten rid of these content types using a more heavy handed/brutal approach but I didn't really have the time, or the tools at hand.

Installing the Add-In

Time for plan B – hope that installing the 'SQL Server 2008 R2 Reporting Services Add-in for Microsoft SharePoint Technologies 2010' works.


Sure enough, following the installation, without modifying what I'd originally deployed – and as if by magic – I was again able to create new sites based on the saved templates </baffled>


Further investigation seems to suggest that the feature dependency existed because the Site Template made reference to the Report Server content types, which, of course, are part of the Report Server feature.

Sunday, 13 June 2010

Sysprep SQL Server 2008 R2

Recently I've been having a little play with preparing stand-alone instances of SQL Server 2008, otherwise referred to as sysprep. I considered writing a guide with screenshots but it's already been done. So in the spirit of not wanting to reinvent the wheel, here we go: http://blogs.msdn.com/b/petersad/archive/2009/12/17/sql-server-2008-r2-sysprep-step-by-step.aspx

Thursday, 13 May 2010

SharePoint 2010 - New Service Application - Application Pool Already Exists!


Whilst playing around with SharePoint Server 2010 there have been a number of occasions where I’ve created a new Service Application, only to find I’ve either done it wrong or need it configured in a slightly different way for whatever reason.



Typically what I’d do is delete the old SharePoint Service Application and create a fresh one. I quite often want to use the same naming convention and this seems to cause problems.



For example, I created a Secure Store Service, realised I’d done something wrong, deleted it and tried to re-create it using the same settings as before. When I try to do so, SharePoint tells me that there’s already a SharePoint IIS Application Pool (SPIisWebServiceApplicationPool) that exists with the same name:

 


 

So the first thing you think to check is IIS, right? I did that and did not see the Application Pool to delete it.


Not accepting defeat and wanting to retain my naming convention I looked into this a little further; Is SharePoint 2010 storing a list of Application Pools somewhere and not clearing them out properly?


After a little searching, it struck me that perhaps this was something I could sort out with PowerShell. Here’s how:-
I queried the list of Application Pools using Get-SPServiceApplicationPool to ensure the one I’d previously created was indeed still there and accessible to PowerShell

 


 

Then it’s as simple as calling Remove-SPServiceApplicationPool to remove it.

 


 

That's it. You've tidied up the the farm by removing the application pool and got to keep your precious naming convention. Thanks PowerShell - I'll sleep easy now.

Wednesday, 25 November 2009

Windows Server 2008 R2: Active Directory Domain Services - Installation Failed

If, like me, you installed Windows Server 2008 R2  and then went on to disable several of the windows services you thought you didn't need prior to installing the Active Directory Domain Services role - you may have noticed that the Installation Fails.

I usually disable services that I feel are not required for what I'm doing. This especially helps create an optimal system when using a virtual machine.

However - learn from my mistake: Don't disable Remote Registry.

Remote Registry is a dependency of DFS Namespaces which is a dependancy of Active Directory Domain Services. Make sure these two services are enabled and you won't experience the same Installation Failed message.

Monday, 21 September 2009

SharePoint Designer: Errors were found when compiling the workflow

The Issue
Recently, while attempting to publishing a SharePoint Designer workflow I was receiving the following error message:

“Errors were found when compiling the workflow.The workflow files were saved but cannot be run”.
Detail: “Unexpected error on server associating the workflow”

I researched the issue and found many suggestions and workarounds for this issue. Fixes and workarounds that worked for others range from Permissions configuration, configuring the correct task list, right through to code fixes. On some occasions the problem was purely a minor detail that had been overlooked by the developer.

Knowing that none of these fixes and workarounds applied to my scenario I was a little baffled to say the least.

What worked for me
A colleague of mine suggested using ProcessMonitor (opens in new window) to find out what was happening when attempting to publish the workflow. What we discovered is that each time I tried to publish the workflow, it was writing to and referencing a cache on the client machine (where SharePoint Designer is running).

Cache Location on Vista/Win2008:- C:\Users\[Username]\ApPData\Local\Microsoft\WebsiteCache

Note: If you happen to know where the cache is located on other operating systems I’d appreciate your input.

Having cleared out the cache the workflows published. Hurrah!

Thursday, 14 August 2008

ECTS & ADAM Gotcha

The Extranet Collaboration Toolkit for SharePoint (WSS v3.0 & MOSS 2007) has a little gotcha which is rather annoying. The gotcha is an auto-append of CN=Users to the LDAP Connection String to the SharePoint web.config file. Here's how it tripped me up...

When configuring the ADAM instance, you are asked to input a User Container Name in the form of part of an LDAP connection string (see screen-shot below):

What this does is create an ADAM instance and a container at the path specified (User Container Name). When the ADAM instance is created, it also creates a sub-tree of CN=ExternalUsers, as shown below:

Now, when you run the ECTS setup wizard to configure and install the SharePoint solutions and features, you are asked to input an ADAM Server Name, you're then asked to provide a User Container Name at which to point the SharePoint solution to enable it to add the LDAP Connection string to the SharePoint web.config file.

Now here's where the gotcha hits - I looked at my ADAM instance using ADSI Edit and supplied the ECTS Setup Wizard with a User Container Name something along the lines of CN=Users,CN=ExternalUsers,DC=server,DC=domain,DC=suffix.

Now, when the ECTS Base feature is activated, it puts several items into the SharePoint web.config file. One of these items is the LDAP Connection String. What I didn't know at that time is that it automatically prefixes CN=Users to the User Container Name that you chose when configuring ECTS for SharePoint.

Given that I specified a User Container Name of CN=Users,CN=ExternalUsers,DC=server,DC=domain,DC=suffix when configuring ECTS for SharePoint, this would of course then become CN=Users,CN=Users,CN=ExternalUsers,DC=server,DC=domain,DC=suffix
(note the repeated CN=Users).

For a while, I manually updated all of the web.config files in my farm that were affected by this. Soon it became quite a burden; every time a modification was made that involved the web.config being re-written from the database, the repeated CN=Users would always re-appear.

I suppose you could put this down to my ignorance, or perhaps you'll agree with me that the documentation doesn't make this as clear as it should be - whichever way, I thought it might be useful to share this.