Tuesday, April 23, 2019

List of actions behavior when updating SharePoint sites with Site Designs

For the last two months I've used Site Designs to update different kinds of existing SharePoint site collections. To be honest, I was very impressed about the good update results. For instance, quickly updating installed apps via Invoke-SPOSiteDesign. In this blog post, I want to share with you a detailed documentation I created about the actions (Site Script verbs) behavior during applying Site Designs to a SharePoint site collection which has already run older Site Design versions.

The table below, shows a list of top level actions:
Action (Verb) Support update Notes
activateSPFeature Yes Adds specified web feature if not yet added. Doesn’t add site features yet! Maybe it will be supported in the future
createSiteColumn Yes Following properties are supported: displayName, group and enforceUnique
createContentType Yes Following properties are supported: description, hidden and subactions
addNavLink No Yes Updating url or displayName is not possible with it. The trick here is to first remove the existing node using removeNavLink and then to re-add it with addNavLink within the same script. Other properties such as parentDisplayName should be supported 
applyTheme Yes Overrides the existing theme
setSiteLogo Yes This action is only supported in Communication Sites. It overrides the existing site logo
joinHubSite Yes If site is already associated to a Hub Site, the current site will be associated to a new Hub Site. If the Hub Site was set up with a Site Design, this Site Design will also be applied
installSolution Yes If site has an older add-in version, applying a new version will update the installed add-in
associateExtension Yes If site has an older extension version, applying a new version will update the installed extension
triggerFlow No You can't update an already triggered Flow instance. Just trigger a new flow instance
setRegionalSettings Yes Overrides existing regional settings. Following properties are supported: timeZone, locale, sortOrder and hourFormat
addPrincipalToSPGroup No Neither removes nor re-adds existing users. Just adds new users to security groups.
setSiteExternalSharingCapability Yes Overrides the existing sharing capability

The table below, shows a list of sub actions to run on the list:
Action (Verb) Support update Notes
setTitle Yes Overrides existing title
setDescription Yes Overrides existing description
addSPField Yes Following properties are supported: displayName and addToDefaultView (only from false to true)
deleteSPField Yes Removes specified field if not yet removed. Even if field has data!
addSPFieldXml Yes Following properties are supported: schemaXml (type, displayName, required, defaultValue etc. Seems to update everything) and addToDefaultView (only from false to true)
addSPLookupFieldXml Yes Following properties are supported: schemaXml (displayName, showField, required etc. Seems to update everything, but I didn’t test other properties) and addToDefaultView (only from false to true)
addSiteColumn Yes Associates site column with default content type only. Updates addToDefaultView property (only from false to true)
addSPView Yes Following properties are supported: query, rowLimit, isPaged, makeDefault, scope and viewFields (add new fields, but doesn’t remove existing ones)
removeSPView Yes Removes specified view if not yet removed. Won’t remove default views
addContentType Yes Adds specified content type if not yet added
removeContentType Yes Removes specified content type if not yet removed. Won’t remove a content type if it is being used
setSPFieldCustomFormatter Yes Following properties are supported: formatterJSON and fieldDisplayName (applies custom formatter to another column)
associateFieldCustomizer Yes Following properties are supported: clientSideComponentProperties and internalName (applies customization to another field)
associateListViewCommandSet Yes I didn’t get this action to work. Test ended up with the following error:
"Associate command set HelloWorld Something went wrong and we could not complete this action."

How did I run my Site Scripts?

I used PowerShell and the SharePoint user interface to apply my Site Design. Running Site Designs through PowerShell is always a fantastic experience. Invoke-SPOSiteDesign returns a quick response even when running a Site Script with many actions. On the other hand, working with Site Designs through the SharePoint user interface was a slow, but very fancy experience.

Summary

Site Designs is a new capability for provisioning in Office 365. If you haven't tried out it yet, then go ahead and give it a try. It supports updating existing SharePoint content in a very stable manner. Did you find a test result different than mine? Then post it as a comment and let us improve these lists together.

Monday, April 8, 2019

Pitfalls when provisioning with Site Designs

This blog post goes beyond the intro level of SharePoint Site Designs and Site Scripts. In detail, I'll demonstrate here common issues that you might encounter while working with Site Designs in real scenarios. Specially the case "applying Site Designs to an existing SharePoint site with custom content" poses risks that shouldn't be underestimated! After reading this blog post, you should be able to avoid these issues which results in less frustration for you while working with the powerful Site Designs.

If you're looking for the basics about SharePoint Site Designs and Site Scripts, consider visiting this blog post.


Cases:

Case 1: Updating an existing navigation link
Case 2: Applying Theme
Case 3: Updating an existing list column
Case 4: Removing an existing list column


Case 1: Updating an existing navigation link

Scenario: A site collection already contains a link called "Learning Portal" in the left navigation. The link must be updated since the learning portal URL has changed.

Site Script: The script defines a new URL for the navigation node "Learning Portal". Here is what it looks like:

{
    "$schema": "schema.json",
    "actions": [
       {
           "verb": "addNavLink",
           "url": "https://docs.microsoft.com/",
           "displayName": "Learning Portal"
       }   
    ]
}

Problem: The unique identifier for the verb addNavLink is composed of url and displayName. You can't use addNavLink to update an existing navigation link. If you run the code above, you'll end up with two similar navigation links:


How to avoid that: The addNavLink alone won't update your link. The trick here is to first remove the existing navigation node using removeNavLink, then add it again with addNavLink. The removeNavLink removes the last node of the navigation node collection. Hence, if you for some reason have more than one node with the same name, only the last one will be removed. Here is what the script looks like:

{
    "$schema": "schema.json",
        "actions": [
            {
                "verb": "removeNavLink",
                "displayName": "Learning Portal",
                "isWebRelative": false
            },
            {
                "verb": "addNavLink",
                "url": "https://docs.microsoft.com/",
                "displayName": "Learning Portal"
            }
        ],
        "bindata": { },
        "version": 1
}


Case 2: Applying Theme

Scenario: Site Design is applied during Hub Site association.

Site Script: The script states that a custom theme is applied to the site collection.

{
    "$schema": "schema.json",
        "actions": [
            {
                "verb": "applyTheme",
                "themeName": "Corporate Identity"
            }
        ],
        "bindata": { },
        "version": 1
}

Problem: By design, Hub Sites passes on its theme to the associated sites. If the Site Design also applies a theme to the site collection, you will override the inherited Hub Sites's theme. When the Hub Site theme is updated, all associated sites will inherit this theme.

How to avoid that: The Hub Site defines the theme for the associated sites. At the moment you can't turn it off. If you apply a theme with a Site Design, remember that it can be changed at any time. The better way is to avoid applyTheme when working with Hub Sites.


Case 3: Updating existing list column

Scenario: In a first step, Site Design was used to create a Customer Tracking list with the Customer Name column. Now, the Customer Name column should be updated using Site Designs.

Site Script: The script states that the Customer Name column will be set as required. Here is how it looks:

{
    "$schema": "schema.json",
        "actions": [
            {
                "verb": "createSPList",
                "listName": "Customer Tracking",
                "templateType": 100,
                "subactions": [
                    {
                        "verb": "addSPField",
                        "fieldType": "Text",
                        "displayName": "Customer Name",
                        "isRequired": true,
                        "addToDefaultView": true
                     }
                ]
            }
        ],
        "bindata": { },
        "version": 1
}

Problem: The unique identifier for the list column is the internal name. If you don't specify it, the internal name will be based on the display name since it is an optional property 😐 If you run the script above, you'll end up with two Customer Name columns with the following internal names: Customer_x0020_Name and Customer_x0020_Name0


How to avoid that: Always specify an internal name when working with addSPField since it avoids  a new similar list column being created. By the way, the only properties you can update using addSPField are displayName and addToDefaultView.


Case 4: Removing an existing list column  

Scenario: A list column was incorrectly created and must be removed.

Site Script: The script states that the list column Customer Name will be removed from the Customer Tracking list.

{
    "$schema": "schema.json",
    "actions": [     
        {
            "verb": "createSPList",
            "listName": "Customer Tracking",
            "templateType": 100,
            "subactions":
            [
                {
                    "verb": "deleteSPField",
                    "displayName": "Customer Name"
                }
            ]
        }
    ],
    "bindata": { },
    "version": 1
}

Problem: The deleteSPField property's displayName must actually be set up with the internalName of a list column. You must be careful working with this action since it also removes already filled in columns! Entering the wrong internalName can result in data loss.

How to avoid that: Always specify the correct internal name when working with deleteSPField, otherwise you might delete the wrong column and lose data.


Summary:

Site Designs is a robust functionality which helps administrators improve provisioning in Office 365. Keeping a couple of scenarios in mind helps to work better with Site Designs. I hope you could learn something new here and can now concentrate on the essentials instead of fixing Site Designs issues.