Upgrade SharePoint 2010 My Sites to SharePoint 2013

There seems to be a lack of information out there regarding upgrading SharePoint 2010 My Sites to SharePoint 2013.

If you try to do a straight “Mount-SPContentDatabase” to a new web application.  This will work partially, as you will be able to get to your “My Site”, however, when trying to go into “Site Settings” or “Site Permissions”, you will get a “404 – File Not Found” for a lot of the back-end system files.

The best way I have found is to set up the My Site Host first in SharePoint 2013, and then run a Mount-SPContentDatabase on your old SharePoint 2010 My Sites database.

1. Backup your WSS_Content_UserSites

2. Restore it to your SharePoint 2013 SQL as a new database

3. In Central Admin, go to “Application Management”, “Manage Web Applications”, choose “New”

4. Once the site is created, choose to “Create a new site collection”, and select the “Enterprise” tab, and “My Site Host” as the type.

5. Once the My Site Host is created, you can attach your 2010 My Sites database:

Mount-SPContentDatabase -Name WSS_Content_UserSites -WebApplication https://mysites.contoso.com

6. Finally, go into your User Profile Service (Application Management -> Manage Service Applications -> User Profile Service).  Click on “Setup My Sites”

7. Enter your My Site Host in the area provided, and don’t forget to add the appropriate groups to “Read Permission Level”

Restoring Local (Farm / Self-Signed) Certificate in SharePoint 2013

If you accidentally delete or overwrite your “local” SharePoint certificate, you may find random things breaking such as Visio or Excel web parts, or things that require authentication.

You can check to see what certificate you have installed, and see if this might be the case by typing the following in Powershell:

Get-SPTrustedRootAuthority

Examine the “local” entry. If it does not say “SharePoint Root Authority” for the certificate, you will need to fix this. It should look something like this if it is correct:

If your cert does not look like the one above, and you have a multi-server farm, you should still be in luck. Log on to one of the other servers, and fire up SharePoint Management Shell.

Type the following:

$localCert = (Get-SPCertificateAuthority).RootCertificate
$localCert.Export("Cert") | Set-Content "C:\localCert.cer" -Encoding byte
Log on to the machine with the incorrect certificate (likely your Central Admin server), and copy the exported certificate there.  Again in PS:
Get-SPTrustedRootAuthority

Find the “Id” for the “local” certificate.
Import the certificate.
$localCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\localCert.cer")

Using the Id you noted above for the “Identity”:
Set-SPTrustedRootAuthority -Identity "3e20f374-6d2e-4115-bbb8-40d9dd803d5d" -Certificate $localCert

Finally, check your work:
Get-SPTrustedRootAuthority

This should put you back in business.

Renewing ADFS 2.0 Certificates in SharePoint 2013

First export your certificate(s) from ADFS.

Log in to AD FS 2.0 Management.  Under “Service”, select “Certificates.”  Find the primary token-signing certificate (the new one you want to renew).  Double click on it, under “Details”, click the “Copy To File” button.  Follow the steps to export it (Choose not to export the private key).  If the certificate has a parent, you may also need to double click on the certificate you are exporting, and export the parent as well.

Copy the certificate(s) to your SharePoint 2013 Server.

From the SharePoint 2013 Management Shell:

Type:

Get-SPTrustedRootAuthority

Find the “Id” for the Trusted Root Authority (certificate you want to update):

Be sure you are selecting the correct Id, and not the Id for the “local” self signed SharePoint certificate.

Next, import the certificate:

$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\newcert\adfs-new.cer")

Then, update the TrustedRootAuthority certificate using the Id you noted above for the “Identity”:

Set-SPTrustedRootAuthority -Identity "da3a4018-993b-4fac-9c31-7ba86ae03114" -Certificate $cert

(You may need to repeat the above steps for the parent cert, if you are updating that as well.)

Check your work, by typing:

Get-SPTrustedRootAuthority

Note the dates for your cert(s) to see if it is current.

Finally, you will also need to update the Trusted Token Issuer.

Type:

Get-SPTrustedIdentityTokenIssuer

Note the name for your trusted token issuer.

Using the Name noted above, update the certificate using the following:

Set-SPTrustedIdentityTokenIssuer "adfs20" -ImportTrustCertificate $cert

Finally, verify your work:

Get-SPTrustedIdentityTokenIssuer

Try logging in.  If all goes well, you’ve earned yourself a coffee.

Setting Up Apps Service (ADFS 2.0 capable) & Where To Install Apps Certificate (*.apps.domain.com)

There seems to be sparse information on how to set up the Apps Service for SharePoint2013 using SSL, especially, if you decide not to set up a separate domain, but rather use a subdomain with a unique SSL cert (*.apps.domain.com).   Most of the setup is fairly straightforward, however, there are a few differences.

First, I do want to note that Microsoft does not recommend this model (http://technet.microsoft.com/en-us/library/fp161237.aspx).  We are doing this because we are using ADFS 2.0 and will be using Apps developed in-house.

Use a unique domain name, not a subdomain
For security reasons, the domain name that you choose should not be a subdomain of the root domain name that hosts other applications. This is because other applications that run under that host name might contain sensitive information that is stored in cookies that might not be protected. Code can set or read cookies across different domains that are under the same domain. A malicious developer could use code in an app for SharePoint to set or read information in a cookie on the root domain from the app for SharePoint subdomain. If a malicious app accessed that cookie information, then you could have an information leak. Internet Explorer honors the settings that SharePoint sites use to protect against this issue. However, you should still use a domain for apps that is separate from your other domains. For example, if the SharePoint sites are at Contoso.com, do not use Apps.Contoso.com. Instead use a unique name such as Contoso-Apps.com. This is not to say that you should never use a subdomain if you have business reasons to do this. However, consider all potential security risks.

This from Microsoft regarding ADFS and SharePoint Apps:

(post) SharePoint-hosted Apps do not support SAML auth – currently SharePoint-hosted Apps will not be redirected to correctly when using SAML auth.  This is because most identity providers (ADFS 2.0 included), do not support wildcards for return URLs – which would be needed due to the isolated domain model implemented for SharePoint-hosted Apps.  However, Azure hosted, or provider-hosted Apps will work when SharePoint is configured to use SAML auth – but there is some configuration required, which Steve Peschka covers off in quite some detail here:  Using SharePoint Apps with SAML and FBA Sites in SharePoint 2013.

With that said, the setup is as follows (in Powershell):

$subService = New-SPSubscriptionSettingsServiceApplication -ApplicationPool “Default SharePoint Service Application Pool” -Name “Subscription Settings Service” -DatabaseName “Subscription_Settings_Service_DB”

New-SPSubscriptionSettingsServiceApplicationProxy -ServiceApplication $subService

Get-SPServiceInstance | where {$_.TypeName -eq “Microsoft SharePoint Foundation Subscription Settings Service”} | Start-SPServiceInstance

Then go into DNS and set up your subdomain for “apps.domain.com” then add a CNAME entry for * to point back to the SharePoint server that has the apps service running.

Head over to Central Admin, go into “Manage Service Applications,” click “New”, select “App Management Service.”

Create a new App Management Service Application, being sure to clear out that nasty Guid and also selecting your default service app pool.

Next go to “Services on Server” and start the “App Management Service.”

You are almost done.  Then click on “Apps” in the left menu (second link from the bottom). Click “Configure App URLs.” Enter “apps.domain.com” and enter an App prefix “app.”

Last step is where the process deviates a bit. You will need to set up a web application without a host header listening on port 443.  This is so that SharePoint can listen for requests that are specific to the apps. Be sure to select “Use Secure Sockets Layer (SSL), and assign it to port 443.

Finally, last step is to install your certificate for “*.apps.domain.com”  I am assuming here you already have gotten one.

  1. Go into IIS Manager.
  2. Find the SharePoint – Apps site you just created.
  3. Click on it, click “Bindings…”
  4. Select the entry with port 443
  5. Click “Edit”
  6. Select the *apps.domain.com certificate
  7. Click OK

That’s it. You should be good to go now!

*I will add a caveat here that I have not built any apps yet, so I have yet to test this all the way through, but this post is based on all the materials I could find, and from what I can tell, it should work.

ID4270: The ‘AuthenticationInstant’ used to create a ‘SAML11’ AuthenticationStatement cannot be null.

During our upgrade to SharePoint 2013 we ran into an issue related to ADFS.  For some reason, SharePoint did not like the SAML coming out of our production ADFS server.  The first cryptic error showed a message indicating:

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client…

Figuring out where to go next required modifying:  C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\WebServices\SecurityToken\web.config, and adding a line to output the debug information.

<behaviors>
<serviceBehaviors>
<behavior name=”SecurityTokenServiceBehavior” >
<!– The serviceMetadata behavior allows one to enable metadata (endpoints, bindings, services) publishing.
This configuration enables publishing of such data over HTTP GET.
This does not include metadata about the STS itself such as Claim Types, Keys and other elements to establish a trust.
–>
<serviceMetadata httpGetEnabled=”true” />
<serviceDebug httpHelpPageEnabled=”true” includeExceptionDetailInFaults=”true” />
<!– Default WCF throttling limits are too low –>
<serviceThrottling maxConcurrentCalls=”65536″ maxConcurrentSessions=”65536″ maxConcurrentInstances=”65536″ />
</behavior>
<behavior name=”ApplicationSecurityTokenServiceBehavior” >
<serviceMetadata httpGetEnabled=”false” httpsGetEnabled=”false” />
<serviceThrottling maxConcurrentCalls=”65536″ maxConcurrentSessions=”65536″ maxConcurrentInstances=”65536″ />
</behavior>
</serviceBehaviors>
</behaviors>

Then, trying to log in again via ADFS, the following message was displayed.

System.ServiceModel.FaultException`1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]: ID4270: The ‘AuthenticationInstant’ used to create a ‘SAML11’ AuthenticationStatement cannot be null.

Firing up Fiddler, and using this article: http://social.technet.microsoft.com/wiki/contents/articles/3286.ad-fs-2-0-how-to-use-fiddler-web-debugger-to-analyze-a-ws-federation-passive-sign-in.aspx, I took at look at the SAML being returned.  Sure enough, the AuthenticationStatement looked just fine, and practically identical to the SAML coming back from our working test instance of ADFS.  Great…where to go from here?

The answer was to add the AuthenticationInstant as a claim in ADFS.

Finally, the last step was to add a mapping to our TrustedIdentityTokenIssuer:

$ti = Get-SPTrustedIdentityTokenIssuer adfs20

$ti.ClaimTypes.Add(“http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant”)

$ti.Update()

$mapNew = New-SPClaimTypeMapping –IncomingClaimType “http://schemas.microsoft.com/ws/2008/06/identity/claims/authenticationinstant” -IncomingClaimTypeDisplayName “AuthenticationInstant” –SameAsIncoming

Add-SPClaimTypeMapping –Identity $mapNew –TrustedIdentityTokenIssuer $ti

Then, one last login.  Boom! Success!