Thursday 5 November 2015

Fractal Provisioner to improve your SharePoint solutions

Take a look at this builder for light customizations:
https://fractalprovisioner.codeplex.com/

Instead of manual configuring web sites hierarchy, lists and web parts, you can package your customizations and deploy them as many times as you want for example for several customers. Or you can deploy it several times in test environment and then finally deploy accepted package in Production.

Monday 21 September 2015

Replicating documents from file share into SharePoint folder

Features:
  • Uploads documents from file share (or local disk) to SharePoint library folder.
  • Creates folder structure.
  • Deletes documents and folders that are not available on file share.
  • Can replicate documents into SharePoint on-premise and SharePoint online (Office 365)
  • Can work with several folder pairs (source-destination)
  • Designed to be scheduled
  • Handles logging
  • Provides errors log
Here is a solution:
https://github.com/shurick81/Sharepoint-powershell-scripts/blob/master/docreplica

SharePoint limits monitoring

SharePoint has a number of limits that may cause versatile problems in case of you cross them.
Here is a description of these limits for SharePoint 2013:
https://technet.microsoft.com/en-us/library/cc262787.aspx
But how easy you can control that you can stay calm? SharePoint is usually a platform that has many owners and administrators for each site collection/site/list. Thus responsibility is blurred. It is not so easy to teach them all how to stay in boundaries and how to control overall limits.
Here is a solution: PowerShell script that allows you to receive an alert when any is crossed or about to be crossed.
https://github.com/shurick81/Sharepoint-powershell-scripts/blob/master/limitsandtrasholdsmonitoring
Currently monitored limits (to be extended if you like this solution):
  • Number of web applications
  • Number of alternative Urls
  • Number of Host Named Managed Paths
  • Number of Path Based Managed Paths
  • Number of App Pools
  • Number of Databases
  • Size of Database
  • Number of items in DB
  • Number of items in list
  • Number of items in list view
  • Number of lookup fields in list view

Wednesday 22 July 2015

PDF-documents preview automated configuration

If your farm has been bound to Office Web Application Server, then you already got nice preview functions for such office document like DOCX, XLSX and PPTX:

image

By default you do not have the same function for PDF files.

You also may find good articles about how to get this behavior for PDF. For example, here is an article about how to configure PDF preview in libraries: http://www.wictorwilen.se/sharepoint-2013-enabling-pdf-previews-in-document-libraries-with-office-web-apps-2013. And here – about preview in search results: http://www.wictorwilen.se/sharepoint-2013-enabling-pdf-previews-with-office-web-apps-2013-march-2013-update.

The last one supposes that you need to manually copy search result type in each site collection where search results are rendered (all site collections potentially).

All these configurations are quite boring and may lead to mistakes. Here is the script that does configuration automatically:

https://github.com/shurick81/Sharepoint-powershell-scripts/blob/master/configure-PDF-preview

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!

Saturday 6 June 2015

Office 365 user without license

When you add new O365 user, there is an option to assign no license. But what exactly features will be available for such users?

First, when I logged in to https://portal.office.com I got this:

image

No nice tiles, no App Launcher icon, no links to any O365 service at all.

I started to open direct URLs for different applications.

I could not open mailbox. I manually requested https://outlook.office365.com and got this:

image

Newsfeed was not working. I tried only SharePoint Newsfeed, not Yammer.

I was redirected to profile page:

image

I attempted to request this URL for OneDrive:

https://tenantname-my.sharepoint.com/_layouts/15/MySite.aspx?MySiteRedirect=AllDocuments

But it redirected me to profile page again.

SharePoint site was available without a problem: I uploaded documents, used office web apps to edit documents, etc. When I tried to go to “About me” to look at profile, I got this:

image

On the other hand, I could manually type my site url and open my profile, edit it, add picture, etc.:

image

It seems like user can get almost all SharePoint Online functionality, but not other O365 services, like Exchange and Skype for Business.

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.