How do you apply multiple DSC configurations? How do you apply multiple DSC configurations? powershell powershell

How do you apply multiple DSC configurations?


You won't find this in the documentation because you (basically) can't do that.

I say basically, because you can do it, in a sense, with DSC Partial Configurations.

These require a different workflow and a different Local Configuration Manager (LCM) setup though. They do not work the way you are envisioning where you create multiple configurations and then apply them one after the other.

This is by design; what you're trying to do isn't really what DSC is for. The idea is that you are supposed to be supplying the (desired) state of the node you're configuring. Applying multiple configurations could easily cause conflicting settings to be applied.

Even with partials, the LCM is generating a single configuration (resolving your partials) and then applying that all at once.


What to do instead:

DSC is light on tooling. It doesn't really have much to say about how you ultimately generate your configs or handle common data, roles, etc. So you already have to roll your own for the most part.

Applying multiple separate configurations is probably something you should be taking care of in your own workflow, leading up to ultimately compiling your (single) MOF per node.

What are Partials For?

There are 2 use cases I can think of where it would be appropriate to use Partials.

First (and this is primarily the role for them Microsoft had in mind) is for larger and more segregated organizations, where different teams have sole responsibility and ownership for their knowledge domain, and you want those teams to be able to write and control their own configurations.

So for example, the OS team might write the configuration for various basic OS config items (setting time zone/NTP, license settings), and maybe they set the LCM setup to pull from the rest.

The DBA team writes a configuration for installing and configuring SQL server.

The security team writes a configuration for setting password policies, firewall rules and enforcement, etc.

These teams have their own procedures and rules and autonomy. They may have their own pull server where they publish these.

The second use case, which is often related to the first, is when you have multiple pull servers, or you want to combine push and pull. I believe that's only possible with partials.


Future

Do note that Windows PowerShell is unlikely to be updated anymore. PowerShell Core (which is based on .Net Core and runs on Windows, Linux, and MacOS) is where the majority of PowerShell development is going at this time.

With that, DSC will be changing too and getting a completely new edition going forward that works better cross-platform.

Just something to keep in mind if you're going down the path of writing a lot of tooling and workflow code to support DSC.


You don't always have to use partial configuration for what you are trying to accomplish. You can use composite configuration to achieve the same depending how you are using these configurations. Here is the translation of your example using composite configuration.

    $Config = @{    AllNodes = @(        @{ NodeName = 'localhost'; PSDscAllowPlainTextPassword = $True }    )}Configuration LocalAdmin{    Param([String[]]$Node='localhost',[PSCredential]$Cred)    Import-DscResource -ModuleName 'PSDscResources'    Node $Node    {        User 'LocalAdmin'        {            Username = 'Admin'            Description = 'DSC configuration test'            Ensure = 'Present'            FullName = 'Administrator Extraordinaire'            Password = $Cred            PasswordChangeRequired = $False            PasswordNeverExpires = $True        }        Group 'AddToAdmin'        {            GroupName = 'Administrators'            DependsOn = '[User]LocalAdmin'            Ensure = 'Present'            MembersToInclude = 'Admin'        }    }}Configuration DisableLocalAccounts{    Param([String[]]$Node='localhost')    Import-DscResource -ModuleName 'PSDscResources'    Node $Node    {        User 'Administrator'        {            Username = 'Administrator'            Disabled = $True        }        User 'Guest'        {            Username = 'Guest'            Disabled = $True        }        User 'DefaultAccount'        {            Username = 'DefaultAccount'            Disabled = $True        }    }}Configuration AllAccounts{    Param([String[]]$Node='localhost',[PSCredential]$Cred)    DisableLocalAccounts localAccount    {       Node = $Node    }    LocalAdmin localAdmin    {        Node = $Node        Cred = $Cred    }}Set-Location $env:UserProfileAllAccounts -Cred (Get-Credential -UserName 'Admin') -ConfigurationData $ConfigStart-DscConfiguration -ComputerName 'localhost' -Wait -Force -Verbose -Path '.\AllAccounts'