Friday 29 May 2015

Eliminating 10016 event id errors

Symptoms


In Windows System Log you have this error: The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID {61738644-F196-11D0-9953-00C04FD919C1} and APPID {61738644-F196-11D0-9953-00C04FD919C1} to the user <domain>\<account>

Solution


This is very common error. You can manually add activation permissions or use any PowerShell script from Internet. My script is better because it does not require any parameter input from you. All user accounts are taken from SharePoint configuration automatically. So all you need is just to run this PowerShell script on all SharePoint servers: https://github.com/shurick81/Sharepoint-powershell-scripts/tree/master/Eliminating-DCOM-activation-errors.
Appreciate when you share your feedback in comments, Watch and Star in GitHub.

Sunday 24 May 2015

Deploying high-trust apps with on-premise multi-tenancy

Task

I needed to deploy console application that utilizes high-trust SharePoint authorization in multi-tenant environment. To be specific, I had about 10 tenants, SPSiteSubscription objects in farm. And I needed to assign permissions so that application was able to create new site collections.

Issue

Previously, when I had task to give permissions, I have used following articles and it worked like a charm:

https://msdn.microsoft.com/en-us/library/office/jj945118.aspx

https://msdn.microsoft.com/en-us/library/office/dn579380.aspx

The main problem here is that these articles provide following command for issuer registering:

$fullIssuerIdentifier = $specificIssuerId + '@' + $realm

New-SPTrustedSecurityTokenIssuer -Name $tokenIssuerName -Certificate $certificate -RegisteredIssuerName $fullIssuerIdentifier –IsTrustBroker

This approach is absolutely ok if your site collections are not linked to subscriptions. Then you just use farm realm.

This approach is ok for those cases when you need to provide permissions for only one tenant. You just use $web.Site.SiteSubscription.Id.ToString() as realm.

But if you need to provide permissions to more then one tenant, then you are in frustration. I had tried different approach before I found the right one.

For example, if you only register farm realm, then applications cannot be authenticated. Application gets 401 error.

The same if you only register with RegisteredIssuerName without realm, only issuerId, like New-SPTrustedSecurityTokenIssuer -Name $tokenIssuerName -Certificate $certificate -RegisteredIssuerName $issuerId –IsTrustBroker

When you try to register issuer for second subscription, you get an error:

New-SPTrustedSecurityTokenIssuer : Exception of type 'System.ArgumentException' was thrown.

Parameter name: newObj

At line:1 char:1

+ New-SPTrustedSecurityTokenIssuer -Name $issuerId -Certificate $certificate -Regi ...

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

+ CategoryInfo : InvalidData: (Microsoft.Share...rityTokenIssuer:SPCmdletNewTrustedSecurityTokenIssuer) [New-SPTrustedSecurityTokenIssu

er], ArgumentException

+ FullyQualifiedErrorId : Microsoft.SharePoint.PowerShell.SPCmdletNewTrustedSecurityTokenIssuer

Solutions

There are at least two possible solutions for that.

First, you have got an error because Name should be unique. On the other hand there is no any obligatory value rules for this parameter. It is up to you what name to provide. Target is that you can distinguish different issuers. So you can specify any distinguishing names for each tenant.

New-SPTrustedSecurityTokenIssuer -Name "tenant1" -Certificate $certificate -RegisteredIssuerName ($issuerId+"@"+$tenant1realm) –IsTrustBroker

New-SPTrustedSecurityTokenIssuer -Name "tenant2" -Certificate $certificate -RegisteredIssuerName ($issuerId+"@"+$tenant2realm) –IsTrustBroker

New-SPTrustedSecurityTokenIssuer -Name "tenantN" -Certificate $certificate -RegisteredIssuerName ($issuerId+"@"+$tenantNrealm) –IsTrustBroker

Another approach is to register certificate without issuer id specifying at all:

New-SPTrustedSecurityTokenIssuer –Name "Contoso Apps" -Certificate $certificate –IsTrustBroker

In this case only clientID and certificate have sense. Issuer id is not inspected in authentication procedure. This approach looks less secure, but requires less administration efforts.

Sunday 10 May 2015

Object doesn't support property or method 'split' in search-driven content web part

Conditions

1. Issue happened after I had upgraded SharePoint Server from Service Pack 1 level to 2015 March Cumulative Update. It is a huge gap, so may be this issue can appear in different combinations.

2. I have got it only when I have configured URLOWSURLH as a Link URL managed property.

image

Symptoms

I have started to receive

image

Sorry, something went wrong.

Display Error: The display template had an error. You can correct it by fixing the template or by changing the display template used in either the Web Part properties or Result Types.

Object doesn't support property or method 'split' (CoreRender: ~sitecollection/_catalogs/masterpage/Display Templates/Content Web Parts/Items_TwoLines.js

Investigation

I started to investigate js. After couple of hours headache I have realized that it falls on calling method “join” on ms_outHtml object. This method, called on array object, tries to join all array items as strings. One of array’s objects is linkURL.

var linkURL = $getItemValue(ctx, "Link URL");

….

ms_outHtml.push( … , linkURL, … )

But when I enabled debug mode and tried to call linkURL.toString(), it caused the same exception: “Object doesn't support property or method 'split'”. At the same time, when I have tried this test on another environment, where cumulative update is not installed yet, I have got no error, but valuable string.

So it seems like Cumulative Update changes object behavior. Previously it could be converted to string but not anymore.

Solution

I have solved it following way

Opened Item_TwoLines.html in SharePoint Designer.

Changed line 66

from

<a class="cbs-Line1Link ms-noWrap ms-displayBlock" href="_#= linkURL =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">_#= line1 =#_</a>

to

<a class="cbs-Line1Link ms-noWrap ms-displayBlock" href="_#= linkURL.value =#_" title="_#= $htmlEncode(line1.defaultValueRenderer(line1)) =#_" id="_#= line1LinkId =#_">_#= line1 =#_</a>

After that linkUrl has been inserted to array as string, issue went away.

You need to save changes in SharePoint to notice effect.

Do not forget to publish major version so not only admins but all users will appreciate your job!

Saturday 2 May 2015

Simplifying Single Sign On for Office 365 users

There are a lot of guides for federation enabling in Office 365.

This is a good example: https://technet.microsoft.com/en-us/magazine/jj631606.aspx

But almost all of them hide from you some unpleasant true: first time users enter Office 365, they should enter their login. Or at least domain, because login page uses domain name to redirect browser to corresponding federation service.

image

I think it is not really convenient and fortunately, I have managed to find workaround for this.

We can specify certain url for home page in Internet Explorer via group policy. For example, we want to direct user to SharePoint host, like http://sapozhkovtest.sharepoint.com, and our upn-suffix (login domain) is sapozhkov.net. Then we need to put following url as a default page via group policy:

https://login.microsoftonline.com/?whr=sapozhkov.net&wreply=https:%2f%2fsapozhkovtest%2esharepoint%2ecom

In this case user will be automatically redirected to ADFS, then back to login page and then finally to SharePoint url.

Friday 1 May 2015

Issue: accounts are not synchronized from AD to SharePoint multitenant profile service application

I have faced with tough break on one project.

Customer had nested users organization units in AD for each tenant:

Domain
   Customers
      Customer1
         Users
            User1
            User2
      Customer2
         Users
            User3
            User4

SharePoint build: 15.0.4693.1000

Profile service was created with -PartitionMode key, so profile database is split to partitions. Each tenant (SiteSubscription) has it’s own partition.

Special PowerShell command for partition creation is run against each tenant:

Add-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Customer1’

Synchronization connection is created and “Customers” organization unit is ticked.

 

Full synchronization runs without any error, I can see import statistic in Central Administration:

MOSS
Stage SharePoint Server import
Additions 3311
Updates 46
Unchanged 0
.............................
Successes 3357
Failures 0
Start Time 4/30/2015 11:00:03 PM
End Time 4/30/2015 11:01:58 PM

Despite that no user profile is created.

No errors in ULS, Event Log and miisclient. At all.

I started to suspect several things including the way how I specify tenant’s OU and connection creation procedure.

I decided to do several experiments. Though it took a while, I think I did not just waste my time because now you do not need to spend your time. Just learn from experiments I have already made.

Test 1. Rough try

First my suspicions were:

  1. SharePoint checks only direct parent user’s organization unit when decides what partition to store it to.
  2. SharePoint compares tenant’s organization unit with only explicitly ticked ones.
  3. When user is imported but not created in database, next synchronization user will not be processed, because there was no change in AD with it so nothing new for provisioning in SharePoint.

I have done 2 things:

  1. Deleted synchronization connection and created new one and ticked customer’s organization units explicitly. So I ticked each “Customer1”, “Customer2”, etc. against single “Customers” object, that I ticked previously when it failed.
  2. Ran following PowerShell command to connect direct user account’s parent:
    Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Users’

Then I ran full synchronization.

As a result I had got all profiles from all “Users” organization units in one tenant that I applied settings to.

To check number of profiles for each subscription I have used following simple PowerShell script:

Foreach ( $sub in ( Get-SPSiteSubscription ) )
{
    $sub
    $serviceContext = Get-SPServiceContext -SiteSubscription $sub
    $profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager( $serviceContext );
    $profileManager.Count
}

Conclusion:

SharePoint checks only direct parent user’s organization unit when decides what partition to store it to.

Test 2. Looking for proper linking

Now I decided to find any way to define specific “Users” for each tenant. So each SiteSubscription should be linked to specific “Users” organization unit.

First of all, I needed to remove mistakenly created profiles. I have run following command:

Remove-SPSiteSubscriptionProfileConfig -id <SiteSubscription>

I have started to check different forms of organization unit specifying:

'Customer1\Users'
'Customer1/Users'
'Customer1*'
'Users,OU=Customer1’
'DomainName/Customers/Customer1/Users'
'*Customer1'

For example,

Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU 'Customer1\Users’

I specified these values for different tenants and started full synchronization again.

I got no profile creation.

Conclusion (preliminary):

The only known way to link organization unit with SiteSubscription is to specify OU name, like “Users”.

Test 3. Refining

That was not actually true that I would prefer but who asked my opinion?

Since I have started experiments, I decided to take some more results.

Here is a suspicion that I finally would like to clarify:

May be users were not provisioned in SharePoint even after I have applied all thinkable forms of OU specifying for simple reason: They were not changed in AD since last sync, so SharePoint decided that there is nothing new to provision in profiles.

I have applied command to link one of subscription with “Users”:

Set-SPSiteSubscriptionProfileConfig -id <SiteSubscription> -SynchronizationOU ‘Users’

I got all profiles in one tenant again.

Conclusion:

There is no need to recreate connection when you change SynchronizationOU. Full synchronization should process them anyway.

Test 4. What to tick

One thing left to clarify: Is there any dependency on level of OU for ticking when synchronization connection creation?

In recent experiments there were explicitly ticked customer’s organization units, like “Customer1”, “Customer2”, etc.

I changed synchronization connection and ticked only parent, “Customers” organization unit.

I had to remove profiles again using Remove-SPSiteSubscriptionProfileConfig/Add-SPSiteSubscriptionProfileConfig, because database was already full of profiles and I needed to clear it to be able to see any synch result.

After full synchronization profiles were created in one particular partition again.

Conclusion:

There is no matter what to tick – one common parent organization unit or explicit children parents. Synchronization mechanism behavior is the same. Also with multitenancy.

Further investigation

After I became more confident that only direct parent name is used for accounts filtering, I succeeded to find related stories in the Internet:

Here Patrick found SQL procedure inside SharePoint databases that makes this “clever” binding:

https://rompenpatrick.wordpress.com/2011/09/16/error-during-profile-import-completed-export-error-ma-extension-error/

And here is a link in this article that refers to forum topic that states:

The developent team (Microsoft support) canned the fix. This functionality will not be part of the CU2 updates or any future updates. They thought it worked as designed:

https://social.msdn.microsoft.com/Forums/office/en-US/e2ac0ff2-0255-4874-9410-5294228a4ece/multi-tenant-user-profile-sync-issue?forum=sharepointgeneralprevious

 

Solution

Not yet. I have not found good solution for my particular project. This behavior means that we should restructure AD. And honestly, this is hardly possible, since customer uses external identity management system to control AD structure and identities. Hopefully I would update this post by some happy end. Later. Thanks for reading this.

P.S.

I have decided to make one more investigation. What will happen if change link to OU and not delete profiles and run full synchronization. In result no new profile was created. All profiles stayed connected to old SiteSubscription. So if you want to connect organization unit to another tenant, do not forget to delete previously created profiles.