PowerShell DSC at a Glance – Frequently asked Questions (FAQ)

PowerShell Desired State Configuration (DSC) is a great way to automate the deployment of any type of environments. The DSC engine has matured a lot over the past 2 years, and is now ready for prime time within the enterprises. However, I feel like this is still a component of PowerShell that is too little known in the industry. Be it because people have not yet heard of it (it was only introduced in WMF4 after all), or because people get scare by its apparent complexity, PowerShell DSC does not yet have the exposure it should. This article aims at answering the most frequent questions I get about PowerShell DSC when I try to introduce its concepts to some of my clients. The answer to the questions are mine, and I am trying to vulgarize the concepts as much as possible.

What is PowerShell DSC?

PowerShell Desired State Configuration (DSC) is an engine within PowerShell version 4 and greater that allows a user to specify an end result configuration (a Desired State) for a machine to be in, and have it automatically configure itself to match that end result configuration.

How does it work?

The Windows Management Framework (WMF) 4 and greater include a service component called the Local Configuration Manager (LCM) that is responsible to orchestrate the configuration of the machine into its Desired State. Via PowerShell, users will create what I refer to as a DSC Configuration Script (which you shouldthink of as a definition/description of what the Desired State should be), and pass it onto the LCM for it to start automating thr configuration.

Why not use a simple PowerShell script to automate the configuration?

Fair question indeed. In the past, we could simply create a .ps1 PowerShell script and execute it manually on a bunch of machines to automate their configuration in a end result state. However, what if that end result state was to change and be modified by somebody on the machine? How can we ensure the machine is always kept in the end result state then? PowerShell DSC tries to solve this by introducing the concept of Configuration Modes. The LCM can automatically detect whenever a machine has steered away from its Desired State and take action.

What type of action can the Local Configuration Manager (LCM) take if a machine steered away from its Desired State

There are 3 types of action the LCM can take if it ever detects that the machine steered away from its Desired State:

  • ApplyOnly: which tells the LCM to simply apply the desired configuration once, and then to do nothing even if the machine steers away from its Desired State.
  • ApplyAndMonitor: which tells the LCM to apply the desired configuration once, and then if the machinesteers away from the desired state, to simply reports discrepancies in the logs. We could then use a tool like System Center to send notifications to the IT team when a server node is no longer in the desired state, allowing them to go an contact the users who changed the Desired State to learn more about why a specific change was made.
  • ApplyAndAutocorrect: which tells the LCM to apply the esired configuration, and whenever it detects that the machine is no longer in a Desired State to automatically fix it so that it becomes compliant with the desired state. Using this mode, the LCM will still report all discrepancies in the logs.

To what frequency is the LCM checking for changes to the Desired State?

By default the LCM will check every 15 minutes to see if the machine steered away from its Desired Configuration, but this can be changed as part of your DSC Configuration Script (definition of the Desired State).

What is a Pull Server?

A pull server is a central repository for all of your DSC Configuration Scripts. When configured in DSC Pull mode, the LCM will ping the Pull Server on a regular basis to check if it Desired State has changed or not.

How can I install a PowerShell DSC Resource?

Go to the PowerShell Gallery PowerShellGallery.com which is supported by Microsoft. The easiest way from there is to ensure your have the PowerShell Get features availble (included in WMF 5). There are instructions on the site on how to proceed from there.

What is a DSC Resource?

Think of a PowerShell DSC resource as a software component that can be configured via PowerShell DSC. For example, if you are to build a new Domain Controller using DSC, once of the component you will need to configure is Active Directory. Well, there is a unique DSC Resource for AD that allows you to configure things like Users, OU, etc. There are even DSC Resources for Firefox and Chrome, assuming you need to install and configure specific browsers on your machine using DSC. DSC Resources are made up of modules, that each take care of a specific component within the software piece being configured by the resource.

Alright, this is normally the point where I’ve lost all of you, so let me try to summarize this further. If we take the Active Directory (AD) example, there is an AD DSC Resource. The component of the AD DSC Resource that allows us to create new users is a module called ADUser. This module contains all the logic required to interact with a User object (CRUD).

How are Modules working internally?

Every module needs to have at least 3 methods: Get-TargetResource, Set-TargetResource, and Test-TargetResource. There is nothing preventing a module from having more than these 3 methods, but these need to exist for a module to be valid.

Get-TargetResource: This method retrieves the current state of the machine. Let me vulgarize the process here a bit. The method performs a scan of the current environment and stores values in a variable (let’s assume it stores it in an XML format). So in our Active Directory example, it will scan all users in AD and will return the current list of users as XML. This method does nothing more than scanning the current environment and returning it CURRENT state.

Test-TargetResource: This method is being called by the LCM everytime it checks to see if the machine steered away from its Desired State. The LCM already knows how the machine should be configured (its Desired State), but it needs to compare it against the Current State to see if they match. To get the Current State, the Test-TargetResource method simply makes a call to the Get-TargetResource method. If the Current State and the Desired State match, then the machine is all configured properly, but if they don’t then that means the machine steered away from its Desired Configuration. The Test-TargetResource method simply returns True or False to the LCM. If the method returns a False, meaning the machine is no longer in its Desired State, then the LCM will need to take one of the 3 actions mentionned above (ApplyOnly, ApplyAndMonitor, or ApplyAndAutocorrect). In the case where the LCM is configured to ApplyAndAutocorrect, LCM will call into the Set-TargetResource method to bring the machine back in its Desired State.

Set-TargetResource: This method is responsible for bringing the machine to its Desired State Configuration based on the DSC Configuration Script (definition of what the Desired State is). When called, this method doesn’t care at all about the Current State. All it wants to do is to bring the environment back to its Desired State. In our Active Directory example, assume the Desired State mentions that a user named “John Smith” has to exist and be part of the Domain Admins group, if someone by mistakes deletes that user, when called this method will automatically recreate the user so that the environment is back to its Desired State.



Configure your SharePoint Environment for SharePointDSC

If you have been paying attention to the SharePointDSC project and always wanted to give it a go but just never had time to actually sit down and get started, this blog post may save you several hours of frustration if you ever decide to start experimenting with the project. When dealing with the SharePoint DSC, most of the calls performed have to be impersonating the Farm Account. Because of this, PowerShell has to do several Remote calls using the Invoke-Command cmdlet, and has to authenticate using CredSSP. By default, CredSSP is not authorized on Windows Server.

Trying to simply run the SharePointDSC scripts against your environment will mostly result in you getting the following error thrown:

Connecting to the remote server <server name> failed with the following error message : The WinRM client cannot process the request. the authentication mechanism requested by the client is not supported by the server or unencrypted traffic is disabled in the service configuration.


Connecting to remote server <server name>failed with the following error message : The WinRM
cannot process the request. CredSSP authentication is currently disabled in the client configuration. Change the
client configuration and try the request again. CredSSP authentication must also be enabled in the server
configuration. Also, Group Policy must be edited to allow credential delegation to the target computer.


In order to fix this, we need to enable CredSSP on both the server and the client. To achieve this, run the following two PowerShell lines of code, where contoso.com is you domain name:

enable-wsmancredssp -role client -delegatecomputer *.contoso.com -force
enable-wsmancredssp -role server -force

SharePoint 2016 Feature Packs

Today at the Ignite conference in Atlanta, Microsoft shared more information about the vision for SharePoint. With SharePoint 2016, it is now possible for organizations to obtain and enable new features within their on-premises environments through the use of “Feature Packs”. In the past, we pretty much had to wait for Service Packs to be released before seeing new features make their way into the product. With Feature Packs, organizations can now activate new features directly into the on-premises product.

The first Feature Pack, scheduled to be made generally available in November of 2016, will introduce the following new features:

For IT Pros

  • Administrative logging: Allowing users to audit actions made in Central Administration;
  • MinRole Changes: Addition of new workloads to support small environments;
  • Unified Logging: Ability to combine logging from both on-premises and Office 365 environments;

For Users

  • OneDrive API Update: One Drive API 2.0 now available on-premises (allows for interaction with Drives and Items);

For Users

  • App Launcher Custom Tiles: Ability to add custom tiles to the App Launcher (waffle icon to left);
  • New OneDrive for Business UX: New User Experience in OneDrive for Business, matching the one introduced in Office 365 last year;
  • Hybrid Taxonomy: Allowing term stores to be unified between on-premises environments and Office 365;


Upload Random Documents to a SharePoint Environment

In my daily job I often need to kill a SharePoint farm and build a new one from scratch to match a client’s Production environment. When doing so, I also need to get rid of any test documents I had created in the previous environment, and need to start creating and uploading new documents from scratch for my new SharePoint environment. While working on a demo for one of my client, I need to demo a SharePoint migration, and also had to give them a live presentation of how the SharePoint 2013 Search Results will be displayed in the new environment.

Because of this requirement, I decided that I needed an automated way to upload thousands of documents, randomly, in my environment. Most of my dev SharePoint environments are single server farms (for simplicity and because it runs directly on Hyper-V on my work laptop). On these local farms, I always install the following software: Visual Studio, Office (2016 or 2013) and SharePoint Designer (yes I said it). The idea behind my automated script was that it should automatically generate Word documents, with random content in them, and upload them in a random site, somewhere in my environment, in the “Shared Documents” library that are included by default in Team Sites.

The first part of the script would have to rely on the Office Interop COM object, which means that ideally Office would have to be installed on the machine running the script. The first thing I did is create an array containing various nouns & verbs. Our script will randomly pick some of these words to populate the content of our Word documents.

$words = @("Cat", "Dog","Cow","Giraffe", "Ball", "Cube", "Sphere", "Document", "Paper", "Computer", "The", "Person", "Black", "Blue", "Red", "SharePoint", "Microsoft", "Red", "Search", "Create", "Delete", "Article", "Web", "HTML", "C#", "VB", "Microsoft", "Job", "Office", "Table", "Star", "Pen", "Pencil", "Arm", "Leg", "Doctor", "Student", "Education", "Defense", "Army", "Navy", "Boat", "Plane", "Jet", "Hockey", "Baseball", "Soccer", "Volley-Ball", "Swim", "Pool", "Lake", "Ocean", "Sea", "Bird", "Fly", "Sky", "Planet", "Space", "Pig", "Owl", "Night", "Day", "Morning", "Evening", "Delete", "Create", "Update", "Great", "Super", "Awesome", "Mark", "Check", "Report", "Minutes", "Decisions", "Technology","Software", "Hardware", "Server", "Database", "Application", "Game", "Keyboard", "Mouse", "Screen", "Tower", "Building", "Street", "Song", "Music", "Car", "Bus")

Next I will be prompting the users to ask them how many documents they wish to randomly upload across the environment. The script will then loop as many times as specified by the user, will generate a random document on each iteration, select a random SPWeb somewhere in the environment and upload the document in its Shared Documents library. Each document will be given a GUID as filename to make sure we don’t hit any conflicts.

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

$words = @("Cat", "Dog","Cow","Giraffe", "Ball", "Cube", "Sphere", "Document", "Paper", "Computer", "The", "Person", "Black", "Blue", "Red", "SharePoint", "Microsoft", "Red", "Search", "Create", "Delete", "Article", "Web", "HTML", "C#", "VB", "Microsoft", "Job", "Office", "Table", "Star", "Pen", "Pencil", "Arm", "Leg", "Doctor", "Student", "Education", "Defense", "Army", "Navy", "Boat", "Plane", "Jet", "Hockey", "Baseball", "Soccer", "Volley-Ball", "Swim", "Pool", "Lake", "Ocean", "Sea", "Bird", "Fly", "Sky", "Planet", "Space", "Pig", "Owl", "Night", "Day", "Morning", "Evening", "Delete", "Create", "Update", "Great", "Super", "Awesome", "Mark", "Check", "Report", "Minutes", "Decisions", "Technology","Software", "Hardware", "Server", "Database", "Application", "Game", "Keyboard", "Mouse", "Screen", "Tower", "Building", "Street", "Song", "Music", "Car", "Bus")

$number = Read-Host "How many documents do you want to randomly upload to SharePoint?"

$allWebApps = Get-SPWebApplication

[ref]$SaveFormat = "Microsoft.Office.Interop.Word.WdSaveFormat" -as [type]
$word = New-Object -ComObject word.application
$word.visible = $false
for($i = 0; $i -lt $number; $i++)
    $filePath = "C:\DND\Documents\" + [guid]::NewGuid().ToString() + ".docx"
    $doc = $word.documents.add()

    $selection = $word.selection
    $result = $selection.WholeStory
    $selection.Style = "No Spacing"

    $rndNumberOfWords = Get-Random -Minimum 1 -Maximum 1000
    $sentence = ""
    for($j = 0; $j -le $rndNumberOfWords; $j++)
        $sentence += $words[(Get-Random -Minimum 0 -Maximum ($words.Length))] + " "

    $selection.font.size = 14
    $selection.font.bold = 1

    $result=$doc.saveas([ref] $filePath, [ref]$saveFormat::wdFormatDocument)
    $result = $doc.Close()

    $randomWebApp = $allWebApps[(Get-Random -Minimum 0 -Maximum $allWebApps.Length)]
    $randomSite = $randomWebApp.Sites[(Get-Random -Minimum 0 -Maximum ($randomWebApp.Sites.Count-1))]
    $url = $randomSite.Url
    Write-Host "Uploading a random document to"$url

    $spWeb = Get-SPWeb $url 
    $docLib = $spWeb.GetFolder("Shared Documents") 
    $allFiles = $docLib.Files 

    $fileName = $filePath.Substring($filePath.LastIndexOf("\")+1) 

    $fileObject = Get-ChildItem $filePath

    $stream = $fileObject.OpenRead()
    $result = $allFiles.Add("Shared Documents/" + $fileName, $stream, $false)
    $fileObject = $null

    Remove-Item $filePath -ErrorAction SilentlyContinue -Force
$word = $null

Upgrade from SharePoint 2010 to SharePoint 2016

In this blog, I will go through the process of upgrading your existing SharePoint 2010 farm to SharePoint 2016. Just like it has been the case with the last 3 product release cycles, there are no In-Place upgrade paths for SharePoint 2016. You basically have to build a new SharePoint 2016 SharePoint Farm, and then bring your content databases over. Throughout this article, we will focus solely on upgrading the SharePoint 2010 Content Databases (data), and not the Service Applications.

Background Information

The first thing you need to be aware of if you are planning an upgrade from SharePoint 2010 to SharePoint 2016, is that there are no direct upgrade path: you will have to upgrade your SharePoint 2010 content databases to SharePoint 2013 before going to SharePoint 2016. However, you do not have to build a complete SharePoint 2013 farm in order to accomplish this. All you need is a standalone SharePoint 2013 server (Single-Server Farm), that will be used as a stepping stone to upgrade the schemas of your SharePoint 2010 content databases to SharePoint 2013, and then move on to your new SharePoint 2016 farm.

Conceptually, the diagram below shows what high-level infrastructure is required for such an upgrade. The SharePoint 2010 section, shows our existing SharePoint farm. For our example, the farm will be made up of two Web Front-Ends, one Application server, and a single SQL Server. Then if we look at the SharePoint 2013 section, we can see that we have a single server farm, that has both the SQL and the SharePoint 2013 bits installed on it. This server will act as our stepping stone to SharePoint 2016. Its sole purpose is to upgrade our SharePoint 2010 content databases to SharePoint 2013 so that we can then move them over to SharePoint 2016. Then, in the SharePoint 2016 section, we see that we have replicated our SharePoint 2010 infrastructure (with new server names to avoid conflicts).


At this point you could have decided to add more capacity to your SharePoint 2016 farm, but to keep things simple we did a one-to-one replica. Another option, depending on how long you can afford to have downtime for your SharePoint farm, would have been to move the content databases to the SharePoint 2013 Single server and upgrade them, to recycle the SharePoint 2010 infrastructure to install SharePoint 2016 on it, and to move the content databases over the newly recycled infrastructure once ready.

Step 1 – Upgrade your SharePoint 2010 content to SharePoint 2013

The first step in our SharePoint 2010 to SharePoint 2016 upgrade process, is to upgrade to SharePoint 2013.

a) Backup your SharePoint 2010 Content Database

  • Launch SQL Server Management Studio
  • Right-click on your Content Databases and select Tasks > Back Up…
    Back Up...
  • In the dialog window that opens, leave the default settings and click OK.
  • Upon receiving a message to let you know that the backup succeeded, click OK to close it.

b) Copy the Backup Files Over to the SharePoint 2013 Single Server Farm

  • By default, the content database will have been backed up in the default SQL installation folder, under the Backup repository. In my case it was located at C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Backup.
  • Take the .bak file and copy it locally onto the SharePoint 2013 Single server Farm.

c) Restore the SharePoint 2010 Content Database on the SharePoint 2013 server

  • Open SQL Server Management Server on the SharePoint 2013 Single Server Farm.
  • In the Object Explorer panel, right click on the Databases folder and select Restore Database…
  • In the Restore Database dialog, select Device from the top radio choices and click on the “…”
  • Keep the “Backup media type” set to File, click on the Add button and browse for the .bak file we’ve copied over.
  • Click OK on both windows.
  • This will initiate the Database Restore operation. Once completed, you will get a confirmation letting you know that the restore operation succeeded. Click OK to close it.

d) Create a New SharePoint 2013 Web Application

In order to upgrade our SharePoint 2010 content databases to SharePoint 2013, we need to associate them with a SharePoint 2013 Web Application.

  • Open Central Administration and navigate to Application Management > Manage web applications
  • In the ribbon, click on New
  • Create a new Web Application on port 80, without a Host Header. By default, if this is the first Web Application you create on your SharePoint 2013 Single Server Farm, the creation interface should automatically default to a new Port 80 web application. Give the Web Application the name Stepping Stone and leave the default options there, and simply click on OK to initiate the creation of the new Web Application.

e) Mount the Content Databases to SharePoint 2013

  • Open a new PowerShell session as administrator
  • Run the following lines of PowerShell. Whis will actually initiate the Upgrade operation on your SharePoint 2010 Content Database.
    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
    Mount-SPContentDatabase "Intranet-Content-1" -WebApplication "Stepping Stone"

    Where Intranet-Content-1 is the name of my SharePoint 2010 Content Database and Stepping Stone is the name of the SharePoint 2013 Web Application we’ve just created in the previous section


  • At this point, you have successfully upgraded your SharePoint 2010 content to SharePoint 2013. In my case, my Content Databases contained 2 site collections, respectively located at /sites/TeamA and /sites/TeamB. Therefore, by navigating to http://<server name>/sites/TeamA I should be able to view my content.

Step 2 – Upgrade the Experience to SharePoint 2013

By default, when upgrading content databases from SharePoint 2010 to SharePoint 2013, site collections will continue to use the SharePoint 2010 experience, meaning that the user interface will continue to look just like it was in SharePoint 2010, even though the engine under the cover is all SharePoint 2013. However, before upgrading to SharePoint 2016, the user experience has to be upgraded to the SharePoint 2013 experience. If you try to upgrade a SharePoint 2013 content database that contains site collections with the SharePoint 2010 experience to SharePoint 2016 the upgrade operation will fail and you will get the following error in the upgrade logs: ERROR Please upgrade sites using SharePoint 2010 experience in database Intranet-Content-1 to SharePoint 2013 before proceeding..

a) Automate the Upgrade Process

  • While you could manually upgrade all site collections to the SharePoint 2013 experience, we will automate the process with PowerShell. The following PowerShell script will loop through all Web Applications in the SharePoint 2013 Single server Farm and will upgrading all site collections to the SharePoint 2013 experience:

    Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
    $webApps = Get-SPWebApplication
    foreach($webApp in $webApps)
        $sites = $webApp.Sites
        foreach($site in $sites)
            Upgrade-SPSite $site.RootWeb.Url -VersionUpgrade -Unthrottled

    * Executing this script will likely take a long time since it synchronously upgrades each site collection one at a time. If you wish to do it in an asynchronous fashion you can use the -QueueOnly switch which will simply put the upgrade request in a queue and will let the timer job get to it at some point in time.

  • To ensure that the experience was properly upgraded, you can navigate back to your site to ensure it now has the SharePoint 2013 look and feel applied to it.
    SP2013 look

Step 3 – Upgrade to SharePoint 2016

The only step remaining is now to migrate our SharePoint 2013 upgraded content to SharePoint 2016. To do so, we will simply repeat step 1, but this time we will bring the data from the SharePoint 2013 Single Server farm onto the newly built SharePoint 2016 farm. I will not be covering the step-by-step procedure to achieve this. Just know that it is exactly the same as what we did to get the content upgraded from SharePoint 2010 to SharePoint 2010. The one difference would be at Step 1-d, where I would off course not recommend creating a Web Application named “Stepping Stone” on your SharePoint 2016 server. You should be mounting your SharePoint 2013 content database against a Production ready Web Application (Step 1-e).

Once the upgrade to SharePoint 2016 is completed, you can navigate back to your site collection to ensure it is properly loading.