Content Database upgrade from SharePoint 2013 to SharePoint 2016 including tweaks and problem solving

As promised, here’s the follow-up blog post to Installing and configuring SharePoint 2016 on-prem (with a combination of PowerShell and Configuration Wizards). Now that SharePoint is up ‘n running with the needed services, it’s time to think about the content. The team site created in the previous blog post had no content, so now we need to import the old content (database) from SharePoint 2013. This is done by upgrading the content database from SharePoint 2013 to SharePoint 2016. Part of the upgrade process happen on the SQL server, as you have to move the existing content database (file) from the old SQL server to the new one. At least this was the case for us, as we also deployed a brand new SQL server (2016) together with SharePoint 2016.

After the content database upgrade process is done, I’ll discuss how to check the status of the upgrade and how to remove old MySites. I’ll also cover Health Analyzer/Timer Job/Event Viewer problem solving, but for now, let’s focus on the content database upgrade. I’m yet again a huge fan of Shane Young’s videos, and in this specific case the video Content database upgrade from SharePoint 2013 to SharePoint 2016.

If you prefer printed text instead of videos, here are a couple of links to get you going:

https://docs.microsoft.com/en-us/SharePoint/upgrade-and-update/overview-of-the-upgrade-process
https://docs.microsoft.com/en-us/SharePoint/upgrade-and-update/create-the-sharepoint-server-2016-farm-for-a-database-attach-upgrade
https://docs.microsoft.com/en-us/SharePoint/administration/move-all-databases
https://www.advaiya.com/blog/how-to-migrate-sharepoint-server-2013-to-sharepoint-server-2016/

 

Here are my own (video)steps recapped:

  • Had a look at our current (old) SharePoint Server to check the content database in use (CA –> Application Management –> Manage content databases):

          sp2016_cdb_view_current_cdbs

  • Went to the old SQL server and looked up the same database (note the ugly DB names btw 🙂 )
    • Right clicked the DB and chose “Tasks –> Back Up…”:

                sp2016_cdb_view_current_cdbs_from_old_sql_management_studio

 

  • On the NEW SQL server, I right clicked on Databases -> Restore Database.
    • I chose the previously backed up database, which was located in c:\backups_from_vasasql:

                sp2016_cdb_restore_cdb_in_sql_management_studio

    • I renamed the database during restore:

                sp2016_cdb_restore_cdb_in_sql_management_studio_choose_name_to_restore

    • I also checked the “Files” tab
      • Nothing to change in my case. The file names were already in the correct format (wss_content_2013.mdf and wss_content_2013_log.LDF).
      • Clicked OK and waited for the restore.
      • Done!

 

  • After a successful restore, I had a look at the database (note the nice DB names btw 🙂 ):

          sp2016_cdb_restored_on_the_new_sql_server

  • I gave the SP_Install2016 account permissions to this newly imported database:
    • Security –> Logins
    • SP_Install2016, Properties
    • Went to the page/tab “User Mapping”
      • put a tick in “WSS_Content2013” and “db_owner”

                sp2016_cdb_access_rights_to_imported_cdb

    • Now moving over to the SharePoint server(s).

 

On the old SharePoint server…

  • checked which managed paths are defined.
    • SP CA –> Manage Web Applications –> Managed Paths:

              sp2016_cdb_check_current_managed_paths

    • my and my/personal are the managed paths that were created from the old “next, next, next-installation”. Not nice. However, I did create these same managed paths on the new server so the content database will have same “layout” after the migration.

 

On the new SharePoint server…

  • I added the above paths on the new server.
  • We now have to delete the current (empty) content database to avoid conflicts when importing the old one.
    • Go to SP CA –> Application Management –> Databases –> Manage content databases
    • Click on the database name (and check that the portal web application is selected).
    • Scroll down until you find “remove content database”

             sp2016_cdb_remove_content_db

    • Click OK to remove it.
  • The content database list is now empty:

            sp2016_cdb_content_databases_overview_empty_list_after_deletion

 

  • It’s now time to import the migrated content database.
    • Shane will actually test the DB before importing it. However, during my tests, I found it easier to first import the database, and do the testing afterwards.Otherwise there are no sites to test against.
    • I actually knew that I had some missing components (intentionally not installed on the new server), and these were easier to deal with after the import.
  • So, we start off by importing/mounting the DB.
    • Start SharePoint 2016 Management Shell as an administrator. Run the following PowerShell command (which I will yet again only provide as a picture):

                sp2016_cdb_mount-spcontentdatabase_powershell

  • It takes some time to complete. In my case it took about 10 minutes. The end result will look something like this:

           sp2016_cdb_mount-spcontentdatabase_powershell_complete

  • I’ll now test the content database for errors. As suspected, the following errors were thrown at me:

           sp2016_cdb_test-spcontentdatabase_powershell_error_overview

                      sp2016_cdb_change_site_collection_administrators

      • another way of adding access to a web application is by changing the policy.
        • SP CA –> Manage web applications –> User policy

                         sp2016_cdb_policy_for_web_application

        • here we give the SP_Install2016 account full permission (which is needed when entering PowerShell commands etc.)
        • I’m not going to copy/paste every single command I ran, so just have a look at the above links and try it yourself.
  • We’re now ready to have a look at the upgrade status.

 

 

(Content database) Upgrade Status

Case: Everything seemed to be working fine when/after you upgraded the content database, and you saw no obvious errors during the upgrade. Still, when looking in SP CA –> Upgrade and Migration –> Check upgrade status, you noticed that something went wrong/wasn’t upgraded. This was at least the case for us:

sp2016_cdb_content_databases_upgrade_status

There’s both a Failed and a Succeeded run in the screenshot, as I managed to fix the problem. The problem was luckily quite easily fixed with hints from:

http://www.sharepointdiary.com/2014/02/upgrade-available-server-status-after-sharepoint-patching.html (just hints, not the actual solution)
https://support.microsoft.com/en-us/help/3157397/upgrade-available-status-in-new-sharepoint-server-2016-farm (solution)

All “symptoms” were true in the second link, and here’s just the first symptom checked:

SP CA –> System Settings –> Servers –> Manage servers in this farm:

sp2016_cdb_configuration_database_upgrade_status

Yes, an upgrade was available.

 

I double checked the same thing using PowerShell:

Get-SPDatabase | select Name, Needs*

The output looked something like this (I’ve cut out the names that didn’t need an upgrade):

Name                                                 NeedsUpgrade        NeedsUpgradeIncludeChildren
——-                                                 ——————         ————————————–
Secure_Store_Service_DB                True                        True
SharePoint_Admin_Content_DB        True                        True
Managed_Metadata_Service_DB       True                        True

 

I also ran stsadm -o localupgradestatus  to get a summary::

[3] content database(s) encountered.
[1] content database(s) still need upgrade or cannot be upgraded.
[20] site collection(s) are contained in the content databases.
[0] site collection(s) still need upgrade.
[32] other objects encountered, [2] of them still need upgrade or cannot be upgraded.

 

As said, all symptoms in the second link were true, so I applied the “fix”:

To resolve this issue, use one of the following methods:

1. Run the following in the SharePoint 2016 Management Shell to upgrade the compoments in the Central Administration database:

Get-SPWebApplication <Central Administration URL> | Get-SPContentDatabase | Upgrade-SPContentDatabase

sp2016_cdb_upgrade_central_admin_components_powershell1

It took a couple of minutes to complete.

2. Run the SharePoint 2016 Products Configuration Wizard from the command line:

PSConfig.exe -cmd upgrade -inplace b2b -wait -force -cmd applicationcontent -install -cmd installfeatures -cmd secureresources”

sp2016_cdb_upgrade_central_admin_components_powershell2

sp2016_cdb_upgrade_central_admin_components_powershell3

Well, that didn’t go exactly as planned. It was mostly my own mistake though, as I ignored the error I got from the Get-SPFarm | Get-SPPendingUpgradeActions –recursive command 🙂 That said, it was easily fixed with information found at https://docs.microsoft.com/en-us/SharePoint/upgrade-and-update/troubleshoot-database-upgrade-issues-in-sharepoint-2013. The SP_Install2016 account once again needed more permissions on the SQL server:

sp2016_cdb_upgrade_central_admin_components_settings_sql_rights

 

I then ran the above PSConfig.exe command again:

sp2016_cdb_upgrade_central_admin_components_powershell_upgrade_success

Yes, happy days 🙂

 

Further checks:

SharePoint CA -> System Settings -> Manage servers in this farm:

sp2016_cdb_configuration_database_upgrade_status_no_action_required

 

SharePoint CA -> Upgrade and Migration-> Review database status:

sp2016_cdb_manage_databases_upgrade_status_ok

 

via PowerShell:

sp2016_cdb_get-spdatabase_needsupgrade_yes_no_powershell

Everything looks OK!

…and as seen in the first screenshot in this chapter, the “Upgrade Status” is now also “Succeeded”. Happy days, everything is working! I’ll now move over to some tweaking and problem solving instead.

 

 

Removing old MySite Site Collections

During the content database migration/import, a bunch of MySites were also imported. To my knowledge, these were in minimal or no usage at all (and had been auto created). My solution was to remove all the unnecessary MySite site collections from the content database. Overall, it was a quite easy procedure based on information found at:

https://sharepoint.stackexchange.com/questions/111263/powershell-delete-remove-all-site-collection-under-a-spesific-managed-path

The command Get-SPSite “https://host.yourdomain.com/my*” –Limit ALL will list all current MySites (which are located under the default web application). This is the default location for MySites when using setup wizards to install SharePoint. Let me copy/paste some information regarding this dilemma:

“At first  having My Site host configured on the default web application may not be a big issue but in the medium to large farm deployment scenarios, you would like to configure the My Site host on the dedicated web application. This would allow organizations to configure the My Sites taxonomy, topology, security, and storage allocations on the dedicated web application running in its own IIS application pool under dedicated service account”.

Source: https://nikpatel.net/2011/06/23/why-you-shouldnt-use-the-farm-configuration-wizard-to-build-production-sharepoint-2010-farm/

Here’s an example output from the above Get-SPSite command:

sp2016_cdb_get-spsite_mysites

As seen from the screenshot, MySites are scattered all over the default web application. Not cool – it gets very cramped in the default web application. Instead, we want to have more control and put the MySite host on a separate web application, my.domain.com for example. This won’t bloat your default web application, and allows for more flexibility and control. I won’t go through the configuration though, as it’s already covered in the post Installing and configuring SharePoint 2016 on-prem (with a combination of PowerShell and Configuration Wizards). Well, back to removing the MySites from the default web application. It’s also easily done with one PowerShell command. BEFORE running this command however, we need to take a backup of the old MySites, JUST IN CASE. Information regarding backup/restore can be found at:

https://social.msdn.microsoft.com/Forums/sharepoint/en-US/de4c8066-035b-4bd6-b3b4-ef0816db4b7e/move-mysites-to-its-own-web-application?forum=sharepointcustomization
https://community.spiceworks.com/scripts/show/1824-export-spsite-export-a-sharepoint-site-to-file (Remember to change the $RootSite parameter)
https://community.spiceworks.com/scripts/show/1837-import-spsite-import-sharepoint-site (Remember to change the $RootSite parameter)
https://sharepoint.stackexchange.com/questions/116422/moving-site-collection-to-a-different-web-application (wouldn’t work for me…)

I had to modify the script in the first link to get it working as intended:

sp2016_cdb_exporting_mysites_for_backup_script

There’s no parameter named “-Path”, instead you should use “-ExportPath”. The script wouldn’t work as intended with the “+ bak” –thing either, so I just removed it. I had no use for .bak extensions on the mysite backups. (If the .bak-part is left unmodified, the script will just create a new directory named “.bak” inside the c:\backup directory, and store all the separate mysite directories inside that directory. This is not the desired effect).

A quick check in c:\backup shows that everything seem ok:

sp2016_cdb_mysites_backup_overview_in_explorer

All MySites are now backed up. The filenames are in the form “$mysite.Name”, which would be domain_username in our case. Even though everything seemed ok, it wasn’t. The log files inside the directories had errors suggesting that my account needed more permissions. Even with the current account added as a Farm administrator and an administrator on the server itself, it wouldn’t work. After much googling I also tried https://social.technet.microsoft.com/Forums/office/en-US/e70019ef-7b18-4fbb-8825-004db9b7deb8/error-while-exporting-subsite-in-share-point-2013-object-reference-not-set-to-an-instance-of-an?forum=sharepointgeneral without success. I then decided that the current backup data was “enough”. Fingers crossed.

 

Now that we have a backup in place, let’s return to the original PowerShell command:

Get-SPSite “https://host.yourdomain.com/my*” –Limit ALL | Remove-SPSite –Confirm:$false

Be warned! The above command will delete all MySite site collections (from the content database). A quick look from the Central Admin confirm that all MySites are gone:

sp2016_site_collection_list_mysites_removed

Yep, all host.domain.com/my/personal/xxxxxx site collections are gone (even though safely backed up).

All NEW MySites will instead be created in their own web application (my.domain.com), because we configured it this way in my previous blog post. The my.domain.com web application doesn’t include the my and my/personal managed paths, because they aren’t needed (and weren’t manually created). Instead, the my.domain.com web application just include the standard managed paths (/personal and /sites). All new MySites will now automatically be created in my.domain.com/personal/username. Good! If I ever want/need to migrate stuff from the old MySites (I doubt it), it’s doable with the backup/restore explained in the links earlier. This is good enough for me. This also quite much summarizes the MySite-part of this blog post. Now let’s look at some other things instead.

 

 

Health Analyzer, Timer Job and Event Viewer problem solving

Health Analyzer problems

Now that you have upgraded the content database and (think) you have a working environment, it’s time to look at the things that aren’t working 🙂 Start by going to SP CA –> Monitoring –> Health Analyzer –> Review problems and solutions. (Your results may vary, and here I’ll present our “health problems”):

sp2016_cdb_health_analyzer_problems

I have the missing server side dependencies problem “under control”, or lets say that at least I know what the problem is. As discussed earlier, the problem is that some features that were enabled on the old server aren’t enabled on this new server (and won’t be). The solution is to manually delete these features etc. from the content database, following information found at:

http://get-spscripts.com/2011/06/removing-features-from-content-database.html
http://get-spscripts.com/2011/06/diagnosing-missingsetupfile-issues-from.html
http://get-spscripts.com/2011/08/diagnose-missingwebpart-and.html

The next “issue” regarding the server farm account is actually a false positive:

sp2016_cdb_health_analyzer_problems2

I’m however following best practices regarding the accounts so I have nothing to worry about. Some more information regarding this false positive:

“Do not change Search Host Controller. For the other services, use one service account for all Service Applications (Instances). There’s no reason to use multiple and will just waste memory/slow down startup time. – Trevor Seward Feb 19 ’17 at 15:06

Thank you for your quick reply, Last query please, Why Host Controller is listed in this case ? and could you please tell me, can I create one service account to run UPS and search? – Mohamed El-Qassas MVP Feb 19 ’17 at 21:35

Because the health rule has no intelligence. It is one of those you will eventually just disable, similar to the 5x RAM free disk space one. Health analyzer rules aren’t hard and fast “best practice”. They’re inflexible and Microsoft isn’t updating them as the product improves; e.g. it will still tell you that 200GB is the limit for content databases, which is far from the truth. – Trevor Seward Feb 19 ’17 at 21:37 “

Source: https://sharepoint.stackexchange.com/questions/208483/the-server-farm-account-should-not-be-used-for-other-services-issue

Furthermore:

SharePoint 2013 Distributed Cache recommendations

The AppFabric “Windows” service should not be touched at all, meaning, don’t change the account manually, nor start/stop the service or change the password for the account. Only exception would be that someone changed the account manually before, and you only want to revert back to the one AppFabric is aware of, but even then it might be better to simply remove and add the server as a Cache Host instead.”

Source: https://blogs.technet.microsoft.com/filipbosmans/2015/10/16/sharepoint-2013-distributed-cache-recommendations/

So, the solution would be to ignore the warning 🙂

 

Timer Job errors

Go to SP CA –> Monitoring –> Timer Jobs –> Check job status –> Job History (menu on the left). Choose “View: failed jobs” in the upper right corner:

sp2016_cdb_timer_job_history_view_errors

Here you’ll find all the failed timer jobs. I’ve been lucky since I’ve got only one failed job 🙂 (Well, I did have a couple more, but they sorted themselves out after a server reboot and some other stuff I can’t remember right now).

Clicking the “Failed” text will get you more information:

sp2016_cdb_timer_job_history_view_errors_in_detail

Unexpected exception in FeedCacheService.IsRepopulationNeeded: Cache cluster is down, restart the cache cluster and Retry

 

This is actually the same information that you’ll find in event viewer:

sp2016_cdb_timer_job_error_in_event_viewer

 

I googled yet again and stumbled upon the following links:

https://blogs.technet.microsoft.com/saantil/2013/03/31/distributed-cache-in-sharepoint-2013-unexpected-exception-in-feedcacheservice-isrepopulationneeded-cache-cluster-is-down-restart-the-cache-cluster-and-retry/
https://social.technet.microsoft.com/Forums/lync/en-US/32e367df-8d79-46a0-9bfe-914f7e8b6492/cache-cluster-is-down-restart-the-cache-cluster-and-retry?forum=sharepointadminprevious
https://ahmedmadany.wordpress.com/2016/02/26/distributed-cache-service-exception-unexpected-exception-in-feedcacheservice-isrepopulationneeded-cache-cluster-is-down-restart-the-cache-cluster-and-retry/
https://guidesharepoint.wordpress.com/2015/05/19/distributed-cache-in-sharepoint-2013-unexpected-exception-in-feedcacheservice-isrepopulationneeded-cache-cluster-is-down-restart-the-cache-cluster-and-retry/

The solution to remove and re-add the Distributed Cache service seemed a bit far fetched. I also checked the third link that mention permissions and accounts, and that part was already OK. I did not try the solution in the fourth link. However, the comment in the second link, “If you can browse your mysite or create a new my site for users it means it’s working. Also check if news feed is updating” made most sense to me. And yes, everything SEEMS to be working so I’ll be ignoring this error for now. Time will tell.

 

Another test would be to run the Troubleshooting Distributed Cache for SharePoint 2013 On Premise script, found at:

https://gallery.technet.microsoft.com/Distributed-Cache-6e8ace1a

and the “manual” for the script found at:

https://blogs.technet.microsoft.com/filipbosmans/2015/09/07/how-to-check-for-issues-with-distributed-cache-and-the-script/

So, just to be sure, I ran the script:

sp2016_cdb_distributed_cache_check_script

After inspecting the output logs (using information from the second link), I found absolutely no errors. This now confirms my theory “time will tell” (if there’s a problem or not).

 

Event Viewer errors

The event viewer didn’t actually contain that much critical stuff of relevance. However, one reoccurring error kept popping up: Distributed COM – Event ID 10016. This is not a critical one, it’s more of a cosmetic fix. Some information regarding this error can be found at:

https://jwcooney.com/2017/08/27/dealing-with-event-id-10016-system-error-logs-with-a-fresh-sharepoint-installation/
https://social.technet.microsoft.com/Forums/windowsserver/en-US/dc4c2b99-72f5-40d8-8b65-6dcdfdb9c084/distributedcom-error-10016-sharepoint-server?forum=winserversecurity
http://www.wictorwilen.se/Post/Fix-the-SharePoint-DCOM-10016-error-on-Windows-Server-2008-R2.aspx
https://soerennielsen.wordpress.com/2007/04/16/fixing-those-pesky-dcom-event-log-error-10016-in-a-sharepoint-farm-environment/
https://blogs.technet.microsoft.com/sharepointcomic/2008/10/28/sharepoint-causes-dcom-errors-event-id-10016/

I myself chose to ignore this error for now. Yes, I’m a naughty boy.

Btw, same thing goes for the following errors:

Another one to ignore is “Session “SharePointDiagnostics” failed to start with the following error: 0xC0000035” – Event ID 2. According to Google, this has to do with the fact that I don’t have the Web Analytics Service installed. See:

https://sharepoint.stackexchange.com/questions/20609/no-health-reports-available-though-features-enabled
http://www.sharepointpals.com/post/SharePoint-2010-Site-Collection-and-Sites-Health-Analyzer-through-SharePoint-Web-Analytics-Services
http://iedaddy.com/2011/05/sharepoint-2010using-web-analytics/

 

Just ignore ‘em all, or at least I did. Do scratch your head even more if you have the energy, or focus on something more interesting/important instead 🙂

 

 

HTTP to HTTPS redirect

As a last tweak, I’ll explain how to configure http to https redirect for the main site. (No one likes to type https in front of url name anyways). This can be done either with SharePoint itself (AAM), or with IIS URL Rewrite Module 2.1. (Both methods require that port 80 is open to the Internet, and obviously that a binding for port 80 exist in IIS). I prefer the URL Rewrite method, so go ahead and grab the latest IIS URL Rewrite Module 2.1 from:

https://www.iis.net/downloads/microsoft/url-rewrite

There are many guides available for redirect, and here’s one random:

http://www.sharepointdiary.com/2015/02/redirect-http-to-https-in-sharepoint-2013.html

For more information about SharePoint AAM vs. IIS Redirect, have a look at:

https://social.technet.microsoft.com/Forums/en-US/c02b2d46-2cd1-43b2-b122-d8324790a753/np-sharepoint-http-to-https-redirect-better-to-do-with-url-rewrite-in-iis-or-aam-in-sp-safe-to?forum=sharepointgeneral

As I said before, I prefer the IIS method and a “clean” AAM.