SharePoint DSC Gotchas and Best Practices

In the Microsoft Virtual Academy on SharePoint Automation with DSC my colleague Brian Farnhill and I recorded in June of 2017, we dedicated an entire module to SharePointDSC best practices. I thought I’d take a few minutes to put the items we discussed during that session on paper. This article will act as a list of the most frequent issues and problem encountered by people using SharePoint DSC. It will be updated as the tool evolves.

Frequent Issues

Installation of Prerequisites, Binaries or Language Pack is Stuck

Symptom:

This is one of the most frequent issue people encountered when starting off with SharePoint DSC. When running the configuration using Start-DSCConfiguration, or when in Pull mode, the installation seems to get stuck when trying to install components (prerequisites, binaries, or language pack). No errors are being thrown.

Most Likely Reason:

There is some level of User Account Control set on the installation file. In most cases this issues will happen when the installation is done from a Network Drive. Upon executing the installation of the component, windows triggers a prompt for the user to confirm the execution of an executable that was launched from an untrusted location, but because this was initiates from a background thread, it is impossible to ever approve that prompt and the installation gets stuck.

In order to test if this is your issue, launch a new PowerShell session, running as the user defined in the PsDscRunAsCredential parameter of the execution block. From there, run the following line of PowerShell. If there are any prompts that appear, that means that the installation is most likely stuck because of the User Account Control.

Start-Process -FilePath <Path to the Installer file> -Wait -PassThru

Solution:

The solution here is two fold. First off, we recommend you turn off the User Account Control feature for the user running the PsDscRunAsCredential installation block in your script. As a second step, launch Internet Explorer and go to Internet Explorer Settings. From there, go to the Security tab, click on the Local Intranet Zone, then click on the Sites button. In the prompt, click on the Advanced button, this will open the window that let’s you specify addresses to identify as being part of the Local Intranet Zone. In that window, type in the location of the Network share (or other common location) where the installer file is located, and click on Add.

Using a completely DSC based solution, you could use the xSystemSecurity module to disable the User Account Control prompt as follow:

# Make sure you import the module
Import-DSCResource -ModuleName "MSFT_xSystemSecurity"

# Put this in the node's configuration;
xUAC NeverNotifyAndDisableAll
{
    Setting = "NeverNotifyAndDisableAll"
}

Best Practices

Master Node

SharePoint is a distributed system, meaning that not all components run on the same server, and that most of the content and configuration is actually stored in a SQL Server database, that all servers in the farm can access at any time. When you define a DSC configuration file, you should identify one of the servers in your farm to be what I refer to has your Master Node. this is the node on which you will define most of the components in the Farm. All other nodes, referred to as secondary nodes in this scenario, should only define resources that allow them to install the required binaries and updates, to join the farm, and the service instances to run on that server. All other components should ONLY be defined on the Master Node.For example, don’t go and define an SPSite entry on multiple node, it is not necessary. SPSite objects are defined in the Content Databases anyway, so you don’t need every server in the farm to attempt to create them.

Take another example where you wish to update the DSC definition of a certain feature on a Site Collection to be disabled instead of enabled. If you properly defined your configuration, you only have to update the DSC definition for that feature within a single node (Master Node) in the DSC configuration file, but let’s imagine you have it defined within every node instead. You now have to go and modify it multiple times within your configuration, and that opens the door to mistakes. Let’s say our farm has 3 servers, that you updated the feature’s definition for Server #1 and #2, but forgot to update the definition in server #3. To make things worst, you’ve set all 3 servers’ Local Configuration Manager (LCM) to be set to ApplyAndAutocorrect. We all know that by default, the ConfigurationMode for the LCM will check every 15 minutes to make sure it is in its desired state, but that 15 minutes may not happen exactly at the same time on each of the servers in the farm. Imagine that at 10h a.m., server one has its LCM kick in, and realize that the feature has to be turned on based on the new definition. It will go and disable the feature. Now, let’s pretend that server #3’s LCM kicks in at 10h05 a.m., but since that server doesn’t have the proper definition, it re-disables the feature that was just turned on 5 minutes ago by Server #1. You can see where this is going, and that can cause a lot of headaches for your admin team. DO NOT DECLARE components (other than SPFarm, SPIntall, SPInstallPrereqs, and SPServiceInstance) on more than one server in the configuration.

Use ApplyAndAutocorrect with Caution

We took a decision a few years back not to let SharePointDSC deal with content such as SPList, SPContentTypes, etc. However, we do deal with items such as SPSite and SPWeb that are stored in the Content Database. The real beauty behind SharePoint is that it lets users deal with their content as they see fit. Users can easily go and create a new list, play with it for a few days, and then decide to delete it after because their tests are done.

PowerShell Desired State Configuration is very powerful. When you set the Local Configuration Manager of a server to ApplyAndAutocorrect, the server will automatically attempt to bring itself back into its defined Desired State Configuration whenever it detects that it drifted away from that configuration. While this feature is very powerful, my recommendation is not to set the LCM in ApplyAndAutocorrect the moment your configuration includes either and SPWeb or SPSite resource declaration, unless you are absolutely certain and aware of what this will do to your environment.

Imagine the following scenario where you have an environment which declares 3 SPWeb (say Web1, Web2, and Web3), and for which the LCM is set to ApplyAndAutocorrect. Come spring, the Information Management (IM) team at your organization undertakes a major cleanup project where they want to get rid of sites that have not been active in the past 6 months. There 3 SPWeb sites defined in the configuration, have been identified by the IM team to be deleted. The IM manager goes in and deletes the 3 sites, then sends an email to the IM director to let him know that the cleanup has been done. Two weeks after the IM director stumbles upon SPWeb2, which the IM Manager claimed to have deleted 14 days ago. Well, the moment the site was originally deleted by the IM Manager, 15 minutes after, the LCM detected that it was no longer in its desired state, and since its LCM is set to ApplyAndAutocorrect, it automatically recreated the site. Imagine the confusion this can cause.

Do Not Have Multiple SPProductUpdate & SPConfigWizard Entries

The SPProductUpdate resource is responsible for installing the bits from a Cumulative or Public Update (.exe) onto a server. When using it in a script that configures a farm from the ground up, the recommendation is to have it executed right after the SPInstall bits have installed the SharePoint binaries, and right before using the SPFarm resource to join the server to the farm. You need to make sure that this resource is applied to EVERY server in the farm, therefore it needs to be defined for each node in your Configuration Script.

The SPConfigWizard resource is responsible for executing the PSconfig process on the servers, committing the bits back to the farm’s configuration database. Once again, it needs to be run on every server in the SharePoint farm, and should therefore appear in every node in your DSC config.

It is obvious why you do not want to have more than one instance of the SPConfigWizard resource defined per server. There are no reasons why PSconfig should be ran multiple time on the server during a DSC consistency check. You also do not want to have more than one SPProductUpdate instance per server. Cumulative and Public updates are cumulative by nature, meaning that for example, you do not need to install the September 2017 Public update before installing the October 2017 Public Update. You simply install the October 2017 PU which contains all the bits from the previous updates as well. If you define multiple SPProductUpdate instances per server, the latest PU or CU will always overwrite the previous version, so you will end up installing old versions of patches, just so that they can be overwritten by more recent ones. Always remember to only have one instance of these two resources per node in your Configuration Script.

this article will be updated on an on-going basis.

2 thoughts on “SharePoint DSC Gotchas and Best Practices

  1. Hi Nik,

    First of all very great blog. I also checked your video demo regarding SharePointDSC and some other of your articles. Now I just started to install my first SP2016 environment using DSC. Your work with Brian is very motivating for me!

    Anyway I would like to ask a question:
    In this blog you states that there is no sense to run the config wizard or updates two times during an installation. Are you sure in this? Maybe I’m wrong but the CU or PU doesn’t contains the language pack updates. Is that correct?
    If not then please do not move on reading. 🙂

    So my main concern is that I want to install a CU/PU then the language pack update. If I run these updates by hand then no metter. I can do it and run one config wizard at the end.
    However if I run the updates from script and do this:
    SPProductUpdate CU
    SPProductUpdate LPUpdate
    SPConfigWizard FinalWizard
    Then this will skip the LPUpdate as it states there is a pending wizard. So the LPUpdate is simple skiepped. Therefore theoretically I need this flow:
    SPProductUpdate CU
    SPConfigWizard CUWizard
    SPProductUpdate LPUpdateWizard
    SPConfigWizard FinalWizard

    Unfortunately this will fail if I use credential encription even if I use the same PsDscRunAsCredential:
    The resources (‘[SPConfigWizard]LPUpdateWizard’ and ‘[SPConfigWizard]FinalWizard’) have conflicting values of the following properties: ‘PsDscRunAsCredential’. Ensure that their values match.

    I found some post regardig this but not too much:
    https://github.com/PowerShell/PowerShell/issues/4138
    https://powershell.org/forums/topic/salted-psdscrunascredentials-considered-conflicting-values/

    Could you please confirm if the CU/PU doesn’t contains the language pack update too? If not then what is the correct handling in this case?

    Thank you in advance!

    Best regards,
    Gabor

    1. Hi Gabor,

      Yes my comment about only running one instance of the SPConfigWizard and having a single SPProductUpdate was related to the cumulative nature of updates. You are correct in that CU and PU don’t include the language specific patches anymore. Therefore, if you use DSC to patch both, you would end up having 2 SPProductUpdate blocks (1 for CU/PU, and 1 for Language Pack patches). You should only need one SPConfigWizard though.

      I hear you about the encryption issue and on the warning saying that a pending ConfigWizard instance. Let me follow-up with my colleagues and see if this is something that can be fixed within the module.

Leave a Reply

Your email address will not be published. Required fields are marked *