Showing posts with label multi-tenancy. Show all posts
Showing posts with label multi-tenancy. Show all posts

Wednesday, 22 July 2015

How to get know if Managed Metadata Service Application is created for multi tenancy

If you have got a farm with already Managed Metadata Service Application created, how can you check whether or not this service application was created partitioned for site subscriptions?
According to Microsoft Technet article https://technet.microsoft.com/en-us/library/ff608097.aspx for creating new multi-tenant service application you usually use following command:
New-SPMetadataServiceApplicationProxy -Name "MetadataServiceProxy3" -ServiceApplication "MetadataServiceApp3" –PartitionMode
But what if service application is already created and you do not know is it site subscription (SPSiteSubscription) aware or not.
When you open service application administration page, there is no any distinguishing attribute you can use.
And there is no any PowerShell command to examine existing service application.
The only way I found is to look at service application properties.
image
image
The only difference I found is Content Type Hub parameter that is visible in case if service application was created without partitioning. Otherwise there is no way to specify Content Type Hub because it should be assigned for each tenant separately, using command Set-SPSiteSubscriptionMetadataConfig.
So now you know at least one approach how to get know if existing Managed Metadata Application Service supports multi tenancy or not. Would be great if you know any other ways to do that, I am looking forward to your comments!

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.

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.