Wednesday, April 27, 2016

First steps with Microsoft Desired State Configuration

It's been a long time since Microsoft set up the way for Desired State Configuration and this technology is spreading pretty fast through system admins. Rare are the people who have not heard of it: no matter if you are a PowerShell expert, or just someone making your first steps with it, DSC is one of the best feature in the language since Windows 2012 R2 and PowerShell 4.0 and a lot of us are already implementing it.

But this is only partially true. It isn't hard to see a great difference in speed of adoption of such things between the US, which are always moving pretty fast toward everything that is new (fellow MVP Mike F. Robbins has almost half of his audience at the PowerShell & DevOps Summit using DSC!), and good old Europe (where I live and work): here most system admins around me and with whom I spend a lot of time are still a bit lost when it comes to using a shell language to administer their systems (luckily with exceptions, such as fellow MVP Fabien Dibot who is doing a great job of evangelist around everything Cloud in France).

For sure Windows PowerShell rise has been incredibly fast, with five major versions in nine years, and most of us weren't ready for the change, but, hey, the change came, so why keep hesitating and risk being left behind for good?

So now the question is how do you get started with DSC. Well, the answer is not so easy. There are for sure a lot of resources out there, but, hey, it's complicated to find a good starting point. When you start looking at it, a lot of terms gravitate around DSC and make understanding more rude: you have Pester, GitHub, modules, resources, you have the PowerShell Gallery and a lot of stuff starting with x's and you have Pull and Push configurations and DSC resources to configure DSC itself. And finally you have DSC for Azure. Feeling left behind can definitively happen here.

So, thinking to all DSC newbies, I decided to write a basic simple blog post to introduce DSC in a simple way. I won't be talking about Push and Pull models, nor about Partial Configurations or Cross-Computer synchronization. And I won't try to explain you the difference between GPOs, SCCM and DSC (fellow MVP Stephen Owen does a good job of explaining it all in his blog post 'DSC vs. GPO vs. SCCM, the case for each.').

Everything starts with a keyword: Configuration.
Get-Command Configuration

CommandType     Name                           Version    Source
-----------     ----                           -------    ------
Function        Configuration                  1.1        PSDesiredStateConfiguration
Configurations are special types of functions which, at their simplest, are composed of a main block:
Configuration NameOfTheConfiguration {
   }
Inside this block come one Node blocks for each target computer to configure:
Configuration NameOfTheConfiguration {
   Node 'SRV1' {
       }
   Node 'SRV2 {
       }
   }
Each Node block contains one or more Resource blocks:
Configuration NameOfTheConfiguration {
   Node 'SRV1' {
      WindowsFeature FeatureName {
         Ensure = 'Present'
         Name = 'Name'
         }
       }
   }
The list of resources you can declare are easily obtained using the Get-DscResource cmdlet:
Get-DscResource -Module PSDesiredStateConfiguration | select name
Name
----
File
Archive
Environment
Group
GroupSet
Log
Package
ProcessSet
Registry
Script
Service
ServiceSet
User
WaitForAll
WaitForAny
WaitForSome
WindowsFeature
WindowsFeatureSet
WindowsOptionalFeature
WindowsOptionalFeatureSet
WindowsProcess
This cmdlet is pretty powerfull and it's not limited to showing you the lists of resources: it can also be used to get the syntax of a specific resource:
Get-DscResource -Name Service -Syntax
Service [String] #ResourceName
{
    Name = [string]
    [BuiltInAccount = [string]{ LocalService | LocalSystem | NetworkService }]
    [Credential = [PSCredential]]
    [Dependencies = [string[]]]
    [DependsOn = [string[]]]
    [Description = [string]]
    [DisplayName = [string]]
    [Ensure = [string]{ Absent | Present }]
    [Path = [string]]
    [PsDscRunAsCredential = [PSCredential]]
    [StartupType = [string]{ Automatic | Disabled | Manual }]
    [State = [string]{ Running | Stopped }]
Here you go, you have the basics: you know that you can write a script which contains a Configuration function which declaratively configures nodes with desired well-known resources. That's all there is to know about it to start with DSC and see if you can get any benefit from it.

Now you are NOT supposed to grab your keyboard and start writing your resources: most of what is used today on servers is already available for you out there, on GitHub and on the PowerShell Gallery: it's been developed by Microsoft, it's been improved by the community, and even if it is experimental (remember the x's?), you can already take advantage of it. But how?

That's the second step in learning DSC and there is a cmdlet for it: Install-Module.

Install-Module (alias inmo) is a cmdlet available for PowerShell 5.0 which does all the work for you: once you know you are interested in a module from the online Gallery, just ask this cmdlet to fetch it for you and store it under the %systemdrive%:\Program Files\WindowsPowerShell\Modules folder hence making it available for all the local users.

Quick tip: to get a list for all your module paths; just query the right variable:
$env:PSModulePath -split ';'
C:\Users\Carlo\Documents\WindowsPowerShell\Modules
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
C:\Program Files\WindowsPowerShell\Modules\
It's interesting to note that this cmdlet accepts pipeline input, so if you do not know the exact name of a module, just use Find Module:
Find-Module -Name "xSys*Sec*" | Format-List

Name                       : xSystemSecurity
Version                    : 1.1.0.0
Type                       : Module
Description                : Handles Windows related security settings like UAC and IE ESC.
Author                     : Arun Chandrasekhar
CompanyName                : PowerShellTeam
Copyright                  : (c) 2014 Microsoft Corporation. All rights reserved.
PublishedDate              : 11/09/2015 23:28:31
LicenseUri                 : https://github.com/PowerShell/xSystemSecurity/blob/master/LICEN
ProjectUri                 : https://github.com/PowerShell/xSystemSecurity
IconUri                    :
Tags                       : {DesiredStateConfiguration, DSC, DSCResourceKit, PSModule}
Includes                   : {Function, DscResource, Cmdlet, Workflow...}
PowerShellGetFormatVersion :
ReleaseNotes               :
Dependencies               : {}
RepositorySourceLocation   : https://www.powershellgallery.com/api/v2/
Repository                 : PSGallery
PackageManagementProvider  : NuGet
AdditionalMetadata         : {versionDownloadCount, summary, ItemType, copyright...}
Then pass the output down to Install-Module:
Find-Module -Name "xSys*Sec*" | Install-Module

VERBOSE: The installation scope is specified to be 'AllUsers'.
VERBOSE: The specified module will be installed in 'C:\Program Files\WindowsPowerShell\Modules'.
VERBOSE: The specified Location is 'NuGet' and PackageManagementProvider is 'NuGet'.
VERBOSE: Downloading module 'xSystemSecurity' with version '1.1.0.0' from the repository
'https://www.powershellgallery.com/api/v2/'.
VERBOSE: Searching repository 'https://www.powershellgallery.com/api/v2/FindPackagesById()?id='xSystemSecurity'' for
''.
...
VERBOSE: Downloading 'https://www.powershellgallery.com/api/v2/package/xSystemSecurity/1.1.0'.
VERBOSE: Completed downloading 'https://www.powershellgallery.com/api/v2/package/xSystemSecurity/1.1.0'.
VERBOSE: Completed downloading 'xSystemSecurity'.
VERBOSE: InstallPackageLocal' - name='xSystemSecurity',
version='1.1.0.0',destination='C:\Users\Carlo\AppData\Local\Temp\820819460'
VERBOSE: Module 'xSystemSecurity' was installed successfully.
Concerning these steps, I have seen system administrators trying to manually download DSC resources from GitHub, unzipping them to C:\Program Files\WindowsPowerShell\Modules\ but being unable to list their content with Get-DscResource:
Get-DscResource xSystemSecurity-dev

CheckResourceFound : The term 'xSystemSecurity-dev' is not recognized as the name of a Resource.
At C:\windows\system32\windowspowershell\v1.0\Modules\PSDesiredStateConfiguration\PSDesiredStateConfiguration.psm1:3983 char:13
+             CheckResourceFound $Name $Resources
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,CheckResourceFound
That's not well documented, but, when you download the zip file for a module, the zipped folder can have a '-dev' extension: in this case you have to remove it otherwise Get-DscResource won't be able to discover it.

That's all for today. Stay tuned for more DSC. Do not hesitate to share!

4 comments:

  1. Great article. Can you point me towards an in depth walk-through on Partial Configurations, Credential and Certificate management and Cross-computer synchronisation? I am trying to design the DSC infrastructure in my environment and it's a little difficult when the complex topics appear to be avoided by most MVPs.

    ReplyDelete
    Replies
    1. Thanks for your positive comment.

      I'll probably write a post in the future about those topics, but not before I have done a good introduction of DSC basic functionalities.

      Also you have to understand that this is something pretty new to most sysadmins, and while the community is starting to adopt the PowerShell/DSC model, there are few feedback from the fields for the moment, so it is hard to know what people are most interested about.

      In the meanwhile I heartedly suggest you to have a look at the blog of fellow MVP Ravikanth Chaganti (http://www.ravichaganti.com/blog/) and to ask question on the Powershell.org forum (http://powershell.org/wp/forum/).

      Delete

Related Posts Plugin for WordPress, Blogger...