Saturday, April 4, 2020

Migration of huge content in Sitecore

 Moving a new website to Sitecore or moving a website from one Sitecore instance to another Sitecore instance deals with huge content migration task. This is how we were able to do that quickly and efficiently.

Scenario 1:

There are two Sitecore instances and the task is to move a website with all its content from instance one to instance two.

  • All the templates, renderings, layout and page structure is all different on instance one and two and hence the traditional packaging do not work.
  • The URL structure should be same on the instance two after the migration so the page items structure under the Home item can be same.
  • The same media/images need to be used on the instance two too.

Content migration in Sitecore

Solution approach:

Content items: Moving the content from one instance to another instance is a tricky part and does need a series of steps.

As the two instances have different templates and renderings, it is not possible to import items. Instead we had to export all the content from pages/items to a CSV file using the Powershell script.

  • At first, we can create all the items which resemble the pages (il just say 'page items') i.e., items which have layout and render into some pages like /home, /contactus, /products etc on the instance two. Hoping to have similar fields on all these items, we can export the content to a CSV file using Powershell script. The exported content can be used while creating the page items on the instance two.

    I assume the fields are mainly page titles, descriptions, SEO fields etc which might remain same on the instance two too.

  • Now go through all the existing pages in the instance one and find the unique page layouts. This should be done based on the layout and components used on each page. Based on this segregation list all the similar pages and export the content on the datasources of the components using a Powershell script.

    Say there is a carousel component used on many pages, exporting this into a CSV looks like column1 with a page item name/path, followed by the columns with data about each carousal/slider component datasource i.e., slider title, slider description, image path/id.

  • Use the exported data to create datasources on the instance two. Assuming all the datasources of page items reside below it (like in the screenshot), we can use the newly created page items on instance two and create their datasources below it.

Image Text

  • As we have the page items and their datasources created, we just need to link these two i.e., we need to add/update renderings with their datasouces using powershell script again.

    Saying these may sound easy but requires expertise in writing Powershell scripts to export content to CSV, formatting content in excelsheet/CSV and updating these again in Sitecore. Thanks to our automation expert we had while doing these.

Media items: As the images/media are same, we have moved the items from instance one to instance two using packaging/serialization. We have created a package with the media items from the root of the site (like /sitecore/media library/Images/Site1) and installed it on the target instance (instance two).

Hope this help you. I try keeping this post updated with different scenarios worked.

Saturday, March 21, 2020

Sitecore PowerShell script to enable Language fallback

 A Sitecore PowerShell script to check if the selected sub tree of items have the language fallback enabled and update the items to enable the language fallback accordingly

Is this not the script you are looking for? Then check this complete list of Sitecore Powershell scripts

Check if language fallback enabled on an Item

The script is used to check an item and all its descendants if the language fallback is enabled. It lists all the items for which the language fallback is not enabled.

Fallback option

The script checks the value in the field ''__Enable Item Fallback'' for each item. This field value is '1' when the language fallback is enabled.

$sourcePath = "master:/sitecore/content/Home/Site1"
$items = Get-ChildItem -Path $sourcePath -Recurse
$rootItem = Get-Item -Path $sourcePath
$items = $items + $rootItem

foreach($item in $items){
    if ($item.Fields["__Enable Item Fallback"].Value -ne "1")
    {
        Write-Host $item.ID $item.Fields["__Enable Item Fallback"].Value $item.Paths.Path
    }
}

Script for updating an item to enable language fallback###

Say if you want to enable the language fallback of an item and all its descendants, then below scripts helps you. It checks each item if the fall back is enabled, if it is not then the script would update the item to enable the language fallback and publishes it. As the __Enable Item Fallback field is a shared field, it need not to be done on each language version separately.

$sourcePath = "master:/sitecore/content/Home/Site1"
$items = Get-ChildItem -Path $sourcePath -Recurse
$rootItem = Get-Item -Path $sourcePath
$items = $items + $rootItem

foreach($item in $items){

    if ($item.Fields["__Enable Item Fallback"].Value -ne "1")
    {
        $item.Editing.BeginEdit();
        $item.Fields["__Enable Item Fallback"].Value = '1'
        $item.Editing.EndEdit();
        Write-Host $item.ID $item.Fields["__Enable Item Fallback"].Value $item.Paths.Path
    }
 
}

LanguageFallback

Hope this helps you. Please comment your thoughts.

Monday, January 20, 2020

How To Fix a Certificate Issue on a Sitecore 9.1 Instance?

 If you ever tried to install a brand new Sitecore 9.1 instance on a not that brand new server, especially if this server already has or had another Sitecore 9.0.x instance installed on it, chances are you faced one or more certificate issues while doing that. And let’s face it, we all know that those problems are the worst since they smell like wasted time…

After installing more than thirty different Sitecore 9.x instances in the last few months and having a lot of issues with those little boys, I came up with this list of the three most common certificate issues and I’m going to show you how to fix them in this blog post.

giphy-5

But before jumping on the list, let’s start by understanding the expected outcome when it comes to the Sitecore 9.1 certificates. Basically, after installing a fictitious new Sitecore instance named coveoticore you should have the following scenario:

Local Computer Certificates

  • Trusted Root Certification Authorities:
    • DO_NOT_TRUST_SitecoreRootCert with private key
  • Personal:
    • One certificate for your xConnect website issued by DO_NOT_TRUST_SitecoreRootCert
    • One certificate for your Identity Server website issued by DO_NOT_TRUST_SitecoreRootCert

Current User Certificates

  • Trusted Root Certification Authorities:
    • DO_NOT_TRUST_SitecoreRootCert with private key
  • Personal:
    • DO_NOT_TRUST_SitecoreRootCert with private key

And more often than not, if you have or had a Sitecore 9.0.x instance and used SIF to install it, chances are you have a self-trusted root certificate that was created without a private key as mentioned here and here. Besides that, it looks that there is a mess about the place it creates the root certificate and then the place it tries to use it. That’s why you should aim to have the right root certificate on both local computer and current user stores as I mentioned above.

 

Most Common Errors You Will Find…

 

1. The Sitecore Instance Certificates Are Not Well Configured

If you are 100% sure that the certificates you have are valid and still your website won’t load properly, maybe it’s a matter of re-configuring them on your website configuration files.

giphy-6

Make sure you have the right xConnect and Identity Server certificate thumbprints in hands. You can find those values by opening the computer certificates manager, double-clicking on your certificate and going to the details tab.

Then, replace the old xConnect Certificate Thumbprint by this new one on the following files:

  • .sc\App_Config\ConnectionStrings.config
  • .xconnect\App_Config\AppSettings.config
  • .xconnect\App_Data\jobs\continuous\AutomationEngine\App_Config\ConnectionStrings.config
  • .xconnect\App_Data\jobs\continuous\ProcessingEngine\App_Config\ConnectionStrings.config

Then go ahead and do the same for the Identity Server Certificate Thumbprint and replace it on the following file:

  • .identityserver\Config\production\Sitecore.IdentityServer.Host.xml

After doing that, double check if the certificates you have on IIS for the above websites are the right ones. Open IIS, click on the Server Certificates button, then find the certificate you want and open it to see the thumbprint. If they are not correct, delete the wrong ones and import the right ones using right-click then import.

iis cert.PNG

 

2. The Sitecore Instance Certificates Was Not Issued By A Valid SitecoreRootCert

That can happen if you realize the Sitecore instance certificates (xConnect and Identity Server) were generated using a self-trusted root certificate that: a) don’t have a private key b) was deleted, maybe by you while trying to fix a certificate issue… yeah, I did it.

giphy-7

If that’s that case and you already have recreated the root certificate, you just need to recreate the website certificates as well and then reconfigure them as I showed to you on scenario 1. Otherwise, start by fixing the root certificated (scenario 3) and then get back here to do the second part of the job.

Start by deleting the xConnect and Identity Server from the certificates store. My two cents they are on LocalComputer/Personal.

local computer personal.png

Secondly, get the thumbprint of your brand new SitecoreRootCert which has a private key on it.

correct self-trusted root cert

Since the Sitecore community loves so much PowerShell (me included) we are going to use it to generate our new website certificates.

Run those command in a PowerShell terminal. Make sure you replace the ID below by the one you got in the previous step.

# Make sure you change those parameter values
$NewCertName = “yourwebsitename”
$RootCertID = “‎C726867D3E81E4C0578AAC0FE6359837D034B818”

$NewXConnectCertName = “$NewCertName.xconnect”
$NewIdentityServerCertName = “$NewCertName.identityserver”
$Signer = (Invoke-GetCertificateConfigFunction -ID $RootCertID -CertStorePath ‘Cert:\LocalMachine\Root’)
Invoke-NewSignedCertificateTask -Signer $Signer -DNSName $NewXConnectCertName,”127.0.0.1″ -CertStoreLocation ‘Cert:\LocalMachine\My’ -Name $NewXConnectCertName
Invoke-NewSignedCertificateTask -Signer $Signer -DNSName $NewIdentityServerCertName,”127.0.0.1″ -CertStoreLocation ‘Cert:\LocalMachine\My’ -Name $NewIdentityServerCertName

If you refresh your Local Computer -> Personal certificate store, you should see the two certificates you just created. Make sure you go back to scenario 1 and change the configuration in order to use these two new certificate thumbprints.

Then, on each one of those new certificates, do right-click, all-tasks, manage private key and make sure you give read access to the respective IIS Application Pool identities.

manage private key add users.PNG

identity server manage private key add users.png

3. The Sitecore Self-Trusted Root Certificate Don’t Have A Private Key

Make sure the SitecoreRootCert has a private key on all the three locations expected as listed at the beginning of this article.

check if has private key.png

Delete every root certificate without a private key. Note that by doing that, all websites using client certificates which were generated using this broken root certificate will stop working. You should recreate those client certificates as soon as you have a new self-trusted root certificate with a private key. You can use the PowerShell script on scenario 2 to do this and then fix the configuration files and IIS settings as described in scenario 1.

If you have at least one SitecoreRootCert with private key among your three locations, you are lucky.

giphy-8

I’m happy to inform you that you can export it to a .pfx file and then import it on the other locations on which you deleted the broken root certificate you had. Do it using the right-click, all-tasks, import.

During the wizard to export the certificate, make sure you select the option to export it with a private key.

export with private key

During the import, the most important thing is to select the option to mark this key as exportable, since this is required by SIF in order to properly install a future Sitecore 9.x instance.

make the key exportable

And that’s it. You are all set when it comes to self-trusted root certificates.

If you don’t have at least one valid self-trusted, you can still create one using the following PowerShell script and then export and import it as I just described above.

Invoke-NewRootCertificateTask -FriendlyName “Sitecore Install Framework” -DnsName “DO_NOT_TRUST_SitecoreRootCert”

Conclusion

It can be painful, but it’s part of the game. Certificate issues are the kind of thing that we all know it’s about to happen, but we try to avoid as much as possible. At least now you know exactly how to fix it if it ever happens to you during a Sitecore 9.1 installation. I really hope that this article can help you in this case, and don’t be shy to reach out on twitter @hsantos_x if you find a scenario which is not covered here.

Sunday, June 16, 2019

Sitecore Serialization and TDS

 Now that we know how to build a Helix solution, we need to make it ready for collaboration.

Yes, I’m talking about DevOps.

Version control is obviously an important part of any software solution. However, a Sitecore solution provides some unique challenges to version control. Any given component in Sitecore exists both in the code AND in the database. If you want one of your coworkers to have the new feature you just created, simply committing your code to the Repo isn’t enough - you also need to find a way to get your Sitecore items over to their Sitecore instance.

The easiest way to export Sitecore items such as templates, renderings, settings, and other kinds of content is to simply create a package. The Package Designer wizard will let you select whichever Items/Nodes you want to export, and creates a zip package. You then install this package on the desired Sitecore instance using the Installation Wizard.

However, as simple as it is to use the Package Designer and Installation Wizard, it can take some time and for a big project the overhead will simply be too expensive. The better solution is to use serialization.

Serialization

In Sitecore, items in the content tree can be “serialized,” meaning they can be converted into text files that are easily shared. Those text files look something like the following:

----item----

version: 1

id: {8B468800-BBCB-4298-AEE5-3CD36CE049F8}

database: master

path: /sitecore/content/Microsites/Home

parent: {360A66E5-5DBF-461D-877A-E430FC4E1995}

name: Home

master: {00000000-0000-0000-0000-000000000000}

template: {A8BA95CB-949E-4F91-BDC2-F33AA0FA600B}

templatekey: Home

created: 20180524T203741Z


----field----

field: {F1A1FE9E-A60C-4DDB-A3A0-BB5B29FE732E}

name: __Renderings

key: __renderings

content-length: 1033

The process of Serialization and Deserialization/Updating is fairly straightforward. In your web root, there’s a Data folder and a Website folder. In the Data folder, there’s a folder called “Serialization” that contains folders corresponding to the databases in the project. In these database folders, the Sitecore content tree is represented (serialized) as nested folders and text files, with every parent node being split into both a text file (for the corresponding sitecore item) and a folder containing its child nodes (which themselves may be a text file and a folder, or just a text file). Simply: serialization converts the content tree from the database into folders and text files and stores them in the ‘serialization’ folder.

There are a few ways to manually serialize Sitecore items directly from the content editor. The easiest way is to simply click on the item in the content tree of the content editor, and click “serialize item”. After processing, you’ll see the text file and any folders in the Serialization folder. Once an item (or item tree) from one Sitecore instance is serialized, you can copy the serialized folder/text files into the serialization folder of the target Sitecore instance. Then, you can choose to “update,” which will merge the serialized items with the current ones in the instance, or you can “revert”, which will erase all changes and items that aren’t represented in the serialization folder.

Through this method of serializing items and moving them from one instance’s “Serialization” folder to another, you can transfer content between Sitecore instances in large batches, making for a less arduous process than creating packages and installing them. However, one major challenge remains: keeping track of which items have been changed.

Setting up Team Development for Sitecore

This is where Team Development for Sitecore comes in. TDS, as it’s commonly called, is a tool for committing and pushing content to a repo the same way we do code. At TechGuilds we use it so multiple developers can work on different aspects of a project at once. It allows you to track all of your .net code and Sitecore content changes in one master repository (in TDS’s terms: a Source Control Management System, or SCMS). Not only does TDS allow you to back up your content as you would your code, but it also allows you to compare incoming changes to that content from other developers. (Note: The other well-known competitor to TDS is Unicorn. However, Sitecore just announced they’re going to buy TDS.)

To set up TDS, you’ll want to follow their step-by-step instructions in the TDS documentation. You’ll have to buy it, but there is a free trial available for TDS classic. The installation process is fairly simple - just make sure you’re installing TDS for the proper version of Visual Studio.

After installation, we can start putting TDS to work. I’m going to show you how to add a TDS project to our Helix structure then deploy multiple TDS projects using a “bundle.”

First, the basics: in our Helix solution in Visual Studio, we should see multiple project folders between our Foundation, Feature, and Project layers. We’ll want to add a TDS project to any of the projects that have corresponding Sitecore items, such as renderings and templates. In our case, any one of our projects has corresponding Sitecore items.

Right-click the project folder in question, then select add -> new project. In the “Add New Project” window, you should see options for TDS projects on the left. Select “TDS Project.” For the name, we’re going to name it after its corresponding VS project. However, there may be multiple TDS projects per project folder, and they may each serve different roles. Master projects contain relevant templates and renderings. Content projects contain non-architectural pieces of content that may use the aforementioned templates and renderings. Finally, Bundle projects link together multiple TDS projects so the user can deploy everything at once.

Since we’re making a TDS project for the TGBlog.Project.Website project, we’ll name it TGBlog.Project.Website.Master. For its location, we’ll save it in src/Project/TGBlog.Project.Website/tds. This way, the “tds” folder lives alongside the “code” folder, and Helix architecture standards are maintained.

Now we need to actually connect our TDS project to Sitecore so we can start tracking Sitecore items. To do so, right-click on the TDS project, select properties, then navigate to the Build tab.

In the TDS project properties, you’ll need to set the Sitecore Web Url, the Sitecore Deploy folder, and check “install Sitecore Connector” to connect to Sitecore. The Web Url should be the host name of your sitecore instance (check your bindings in IIS for accuracy). The deploy folder is your Sitecore instance’s web root. Also, you need to enter a valid build output path. (You may want a custom build output path for each configuration, but more about configs in a second.) After you’ve entered these values, click the “test” button to make sure the connection is secure.

Now, you’re not going to want to have to change these settings for every single TDS project you create, so you’ll want to create a global config item. Doing so is easy: right-click the solution in the solution explorer and select Team Development for Sitecore -> Add Global TDS Config file. When you do so, a file called TdsGlobal.config will be added to the solution. This file will be mostly commented out.

We want to standardize the addresses for the Web URL and the Deploy folder. To do so, we’ll need to create or fill out a <PropertyGroup> section. Each <PropertyGroup> section in the config is connected to a build configuration, such as debug, release, or whatever custom configs you might have. For this example we’ll fill out the ‘Release’ section.

First you’ll want to uncomment <SitecoreWebUrl>, <SitecoreDeployFolder>, <InstallSitecoreConnector>, and <SitecoreAccessGuid>. We’re going to populate these fields with the same information we put into the “Build” tab of the TDS project properties page. You can get the Access Guid by returning to your TDS project’s build tab and checking the “Install Sitecore Connector” box. When you do, the above “Sitecore Access Guid” field will populate with a random GUID, which you can copy and paste into the config.

After you’ve created the settings for the chosen Solution Configuration, save. Now, go back to your TDS project properties’ build page. Make sure the Configuration setting in the top left is set to the Property Group settings you created in TdsGlobal.config. When the build page is set to the right config, you should see the settings you filled out in the config file, with an icon of a globe to the right of each field.

Now, any time you create a new TDS project, the build settings should be pre-set. Thanks, global config file!

Getting and Syncing Items

Finally, we’re going to get to use TDS for its intended purpose: tracking Sitecore items that correspond to our code. There are two relevant processes you need to be aware of.

The first TDS process you’ll end up using regularly is the “Get Items” process, in which you simply navigate the content tree and select the Sitecore items you want to track in your TDS project.

Right-click on your TDS project and select “Get Sitecore Items.” 

From the next window, you can choose which items to track in your TDS project by either checking the box next to them or right-clicking a node and selecting “Select all Children.”

In the Solution Explorer, you should now see your tracked items underneath your TDS project when expanded. To stop tracking an item, simply delete the node from the tree under the TDS project.

That’s how to start and stop tracking items in your TDS project! However, you’ll also need to sync your items whenever you update them - this is the main strength of TDS.

Syncing is about as easy as grabbing items in the first place. First, right-click your TDS project and select “Sync With Sitecore.” You’ll then see the Sync screen, along with any changes to the items tracked in your TDS project. If the items in Sitecore or your project don’t match, you can choose to either update the project or update your Sitecore instance. If you make a change on Sitecore, you’ll want to update your project, and if you’re taking a change from the source control, then you’ll want to update Sitecore.

Click “Do Updates” and both your TDS project and Sitecore instance will be updated with whatever changes you decided to commit.

Between Getting Sitecore items to track and updating those items with the Sync feature, you should now have some TDS information to commit to your source control. If you’re using a Git client like GitKraken, you should also see the individual serialized Sitecore items in the project now.

These serialized items are what you’ll ultimately push back to your source repo, and you’ll receive changes the same way. However, now you have a new problem: how do you keep track of and deploy all of these Sitecore item changes?

Deployment and Architecture

There’s not one right way to do architecture. At TechGuilds we always try to use Helix principles as our guide when it comes to architecture, splitting our solution into Foundation -> Feature -> Project layers, with each layer depending on the last. In the VS solution we have multiple projects per layer, with the Feature project most commonly holding our components, the Project layer holding our layout and styling data, and the Foundation layer holding universal standards and any modifications or extensions we may make to Sitecore itself.

We organize our data in the Sitecore content editor the same way, with Templates, Layouts, and other essential folders all having Foundation, Feature, and Project folders. This division makes it easier for us to track our items in a TDS project. For example, if I have a TDS project in the Feature layer that tracks a specific component’s relevant Sitecore items, I know to look for them in the Feature sub-folder in the “Templates” and “Layouts” sections.

However, all of this stuff can quickly become difficult and costly to track. Developers may find themselves asking other developers exactly which Sitecore items they need to update or delete from the project.

Enter Bundles. Bundles allow users to deploy their entire project at once, including every TDS and Visual Studio project. Ideally you would do this once any time you pulled down new code or merged it into your branch.

Before we set up a bundle though, we need to make a couple other changes.

First, in order to deploy code along with our TDS items, we need to link a web project to our TDS project. In the properties page of our TDS project, we’ll select the corresponding VS project in the “Source Web Projects” field.

One more thing: You’ll need to make sure that TDS can reach the proper assembly DLLs. You can either do this through setting the path in the “Sitecore Assembly Path” field on the “Update Package” tab in the TDS properties, or you can use Nuget Package Manager to include references to Sitecore.Update, Sitecore.Logging, and Sitecore.Zip in your solution.

Finally, you can use TDS to help build your project. With the TDS project linked to the web project, you can simply right-click the TDS project and click “build” to deploy your linked VS project(s). If you right-click the TDS project and click “deploy,” it’ll use the Sitecore connection you set up to deploy the Sitecore Items you’re tracking through TDS as well.

Now that we know how to link our TDS projects to our VS projects to make deployment simpler, we’ll make the final step of bundling everything together.

First, make a new TDS project. This will be our bundle project. I’m going to put mine in the same place as our other project, in the Project folder, and I’m going to call it TGBlog.Project.Website.Bundle. Open the properties for this bundle project and navigate to the “Multi-project Properties” tab. At the bottom of this screen you’ll see a field called “Package Bundling.” Here you’ll simply include every TDS project you want to be included in your bundle.

(You can also take the time to add any stray visual studio projects to the “Source Web Projects” field in the “General” tab. You would do this if you had a project you wanted to include in the bundle that didn’t have a corresponding TDS project and/or wasn’t brought in through a dependency reference.)

Once the Bundle project is set up correctly, you can Build or Deploy with it the same way you would any other TDS project, only the Bundle will build and deploy EVERYTHING.

Conclusion

And that’s how you use the basic features of TDS! Today I showed you how to install TDS, how to set it up, how to track and sync Sitecore items with it, and how to make a bundle to deploy your project. Please let us know if you have any questions or comments!

If this is the first post you’ve read in this series, you can also read the following for more information:

Back to Basics, Part 1: Setting up a Sitecore Helix Solution from Scratch

Back to Basics, Part 2: Sitecore Helix Styling with Gulp