In this article we will cover the process of writing a DSC Configuration with SharePointDSC and deploying it to multiple servers to create a SharePoint 2016 farm (note that this would also work for SharePoint 2013 with minor changes to the SPFarm block). We will be using a Push Refresh mode, meaning that the Configuration will be manually applied to our servers, and not using a Pull Server to centrally manage the configuration. Using this approach, if our configuration was to change, it would need to be manually re-pushed onto the servers in the farm. While I believe that in most cases, you will wish to use a Pull refresh mode along with an Enterprise Pull Server to manage your SharePoint deployments, we are using a Push mode to keep things simple for the sake of this article.
The article will cover a scenario I will be demonstrating over at SPTechCon Austin next week. In this demo, I have a very small multi-server SharePoint 2016 farm that is made up of one dedicated SQL Server 2016 (SPTechCon-SQL), one Web Front-End (SPTechCon-WFE1), and one Application Server (SPTechCon-APP1). The configuration script will be built on a separate machine named (SPTechCon-Pull) and will be remotely applied to the servers in my farm from that machine. The figure below gives you a complete overview of the landscape of my demo.
Every server in my farm is a Windows Server 2016 Datacenter instance. As mentioned above, SPTechCon-SQL has SQL Server 2016 installed on it, and both SharePoint boxes (SPTechCon-WFE1 and SPTechCon-APP1) have the SharePoint 2016 bits installed on them (PSConfig was not run, just the SP2016 bits were installed).
As part of the demo, I will be using the following DSC configuration script to deploy my farm:
Configuration SPTechCon-OnPrem { Import-DSCResource -ModuleName SharePointDSC $farmAccount = Get-Credential -UserName "contoso\sp_farm" -Message "Farm Account" $adminAccount = Get-Credential -UserName "contoso\sp_admin" -Message "Admin Account" Node SPTechCon-WFE1 { SPFarm SPFarm { DatabaseServer = "SPTechCon-SQL" FarmConfigDatabaseName = "SP_Config" Passphrase = $farmAccount FarmAccount = $farmAccount AdminContentDatabaseName = "SP_AdminContent" PsDSCRunAsCredential = $farmAccount ServerRole = "WebFrontEnd" Ensure = "Present" RunCentralAdmin = $true CentralAdministrationPort = 7777 } SPManagedAccount FarmAccount { AccountName = $farmAccount.UserName Account = $farmAccount PsDSCRunAsCredential = $farmAccount DependsOn = "[SPFarm]SPFarm" } SPManagedAccount AdminAccount { AccountName = $adminAccount.UserName Account = $adminAccount PsDSCRunAsCredential = $farmAccount DependsOn = "[SPFarm]SPFarm" } SPServiceAppPool SharePoint80 { Name = "SharePoint - 80" ServiceAccount = $adminAccount.UserName PsDSCRunAsCredential = $farmAccount DependsOn = "[SPManagedAccount]FarmAccount" } SPWebApplication RootWebApp { Name = "RootWebApp" ApplicationPool = "SharePoint - 80" ApplicationPoolAccount = $adminAccount.UserName Url = "http://SPTechCon-WFE1" DatabaseServer = "SPTechCon-SQL" DatabaseName = "WebApp-SharePoint-80" Port = 80 PsDSCRunAsCredential = $farmAccount DependsOn = "[SPServiceAppPool]SharePoint80" } SPSite RootSite { Url = "http://SPTechCon-WFE1" OwnerAlias = $adminAccount.UserName Template = "STS#0" PsDSCRunAsCredential = $farmAccount DependsOn = "[SPWebApplication]RootWebApp" } } Node SPTechCon-APP1 { SPFarm SPFarm { DatabaseServer = "SPTechCon-SQL" FarmConfigDatabaseName = "SP_Config" Passphrase = $farmAccount FarmAccount = $farmAccount AdminContentDatabaseName = "SP_AdminContent" PsDSCRunAsCredential = $farmAccount ServerRole = "Application" Ensure = "Present" RunCentralAdmin = $false } SPServiceInstance BusinessDataConnectivityServiceInstance { Name = "Business Data Connectivity Service"; Ensure = "Present"; PsDSCRunAsCredential = $farmAccount; } } } $ConfigData = @{ AllNodes = @( @{ NodeName = "SPTechCon-WFE1" PSDscAllowPlainTextPassword = $True PSDscAllowDomainUser = $true }, @{ NodeName = "SPTechCon-APP1" PSDscAllowPlainTextPassword = $True PSDscAllowDomainUser = $true } ) } SPTechCon-OnPrem -ConfigurationData $ConfigData Start-DSCConfiguration SPTechCon-OnPrem -Wait -Verbose -Force
In summary, that script will automatically create the SharePoint 2016 farm, assign the Web Front-End MinRole to SPTechCon-WFE1, create a Web Application on port 80, and a root site collection, add SPTechCon-APP1 to the farm with the Application MinRole and have it run the Business Connectivity Service. Nothing too complicated, again to keep the demo focused and concise. Now, if you take a look at the last two lines of the script, you see that we are passing ConfigurationData to our Configuration method to ensure passwords can be passed as plain text. In an enterprise context, you will normally want to encrypt the credentials using a certificate. In our case here, I omitted to specify a certificate for simplicity sake.
Let us now head onto our SPTechCon-Pull machine, which is noting but a windows 10 machine hosted on the same domain as our servers to be configured. You will need to make sure that this machine has the SharePointDSC modules installed on it, because it will be required in order for us to compile our MOF file from this server. Installing the module is as easy as running the following cmdlet if your machine has internet connectivity:
Install-Module SharePointDSC
If you machine doesn’t have internet connectivity, then you will need to manually copy the SharePointDSC module onto the machine, under C:\Program Files\WindowsPowerShell\Modules\.
Upon executing the script above, you will be prompted to enter the credentials for the Farm account, which is required to execute the configuration steps, as well as for the admin account’s credentials, which I use as the owner of my site collection. Using remoting, PowerShell will remotely contact the two SharePoint servers and initiate the configuration. After a few minutes, you should see that the execution completed (see figure below).
You should also be able to navigate to the site collection we created (in our case at http://sptechcon-wfe1/) or to central administration, which based on our script, is hosted on SPTechCon-WFE1 and exposed through port 7777.
What is important for you to take away from this example, is that you don’t have to physically go on each server node that are part of your DSC configuration script in order to push the configuration onto it. This can all be done remotely from a machine that is external to the farm, as long as that machine has the SharePointDSC bits installed on it.
Is there a specific reason that your SharePoint Farm is using Windows Server 2016 Datacenter and not Windows Server 2016 Standard
Hi Paul,
No, there are no reasons for it. It would work just as well with the Standard Edition. Thanks
Hi Nik,
G’day mate!
I am trying to install SP2013 following your instructions. It is failing with an error saying “PowerShell DSC resource MSFT_SPFarm failed to execute Test-TargetResource functionality with error message: Server role is only supported in SharePoint 2016.”. Could you please let me know what changes need to be done for SPFarm resource for SP2013 installation.
Cheers.
Can you please post your DSC script? Just make sure the ServerRole property is not included in the SPFarm block for 2013
Hi Nik, thank you for inspiring article.
To be specific, the machine where you execute mof-file should not necessarily run SharePoint binaries. I only installed SharePoint DSC resources on my admin machine and executed the configuration from there, it worked perfectly.