Where would you use "nested(composite)" configurations?


I’m confused of the purpouse of composite configurations (https://docs.microsoft.com/en-us/powershell/dsc/compositeconfigs) and how is it different from just using the same DSC Resource specified in different module? Is it just cleaner way of doing the same thing without neccessity of additional module installation and importing DSC Resource into configuration?

Hey GS! I’m going to put a caveat up front, I’m still working through some of the hairy bits of composites myself. I don’t have all the answers yet. However, I’ve found there are 3 major differences between using a composite and just re-using the same code in multiple configs.

  1. Reporting

This applies more to desktops than servers, but it might still be useful to some people. When a composite is compiled, the resourceID is updated to include the name of the composite. If you use the file resource (MyFile) inside an “xCriticalConfigs” resource, it would have a resourceid of [file]MyFile::xCriticalConfigs. If you were using a reporting solution, you could split out on the “::” and use the composite’s name as a category. This way, you can determine whether a noncompliant system is missing a “nice-to-have” setting, or if it’s missing a critical configuration, like your security agents or something similar.

  1. Testing

If you keep your composites small, they’re easier to run tests against. If you created a testing suite for each composite, it would help you catch issues before they even make it to your testing environment. Below is a mocked-up Pester test, one that ties into item 3.

Describe “Testing Resource” {

Load and run the DSC composite resource

It “Should deploy license file”{}
It “Should install agent” {}
It “Should disable download feature” {}

  1. Parameterization

You can add parameters to a composite, which allows you to control how something is done. For example, look at software management through Chocolatey. It requires that you deploy a license file, install the agent, configure several features, and then register/unregister nuget repositories to control what locations the agent can use to install software. In your desktop environment, you want to enable the self-service feature for non-admins and register the desktop software repository. For servers, you of course do not want to enable non-admins to install software. You could type out the separate DSC statements in every DSC script and edit them slightly depending on desktop/server, but that would be error prone and time consuming. Instead, a better option is to use a composite with a -Type parameter. I included something I mocked up to show what it would look like:

Configuration ChocoAgent {
Import-DSCResource -ModuleName cChoco

Use file resource to install license file

Use cChocoInstaller to install agent

Disable download progress feature to fix overload issues in WinRM

switch ($Type)

Register desktop repos

Disable non-admin access to public repositories

enable self-service


Register server repos

Disable public repositories entirely

Apply FIPS mode



I’ll add a couple thoughts to this. We currently have a few fairly large DSC configurations. These were created before I started with DSC here and knowing what I know now, I probably would have done things differently.

Our configurations were set up as composites for modularization and reusability reasons. The person who created them comes from a software development background so I’m not overly surprised. Basically, they broke down the pieces of our configuration into related pieces. We have one that installs Windows features, one that configures IIS settings, one that configures event log settings, etc… The idea was that not every server was going to need all of those configurations so they were broken out into composites. We then have a DSC configuration for a particular server type (Web server or Non web server for example) which references only the composites that that server type needs.

The other reason for using composites to modularize configurations was we could update the version of a particular composite when changes were made to one of it’s resources without having to update the entire configuration. If a composite gets updated, the new version of the DSC config just gets updated to use the new composite version hopefully reducing the chance of it breaking a single, large configuration.

That being said, I mentioned earlier that I probably would have done things differently knowing what I know now. Composites are a little complicated to create and are easily broken if you make a mistake and don’t name certain things just so. In a large configuration with nested composites like we have, that can make troubleshooting a nightmare. We have a couple configurations that reference a composite, which references a couple more composites and one or two of those composites might also reference another composite. Ugh. My next initiative is going to be to convert our composite configurations to Configuration Data. I would recommend at least looking into using configuration data as an alternative if you haven’t already.

I attended this session at this past PowerShell Summit and I feel like Jason does a real good job of describing the “Configuration Data problem” and why configuration data is probably the way to go. It really helped it click with me.

Here are a couple other resources if you need them:



I watched through the videos and articles and I’m confused how it can be properly applied in my speficic case where I don’t have pull server or any other sort of central configuration management and I have to rely on Octopus Deploy to deploy my configuration to specific nodes. ConfigurationData approach seems to be relying on defining entire infrastructure data in single file and then generating a bunch of MOF files for different types of servers. In my case only 1 MOF files is needed for specific server octopus is working on. I’m struggling to figure out what is the best way to still preserve hierarchical capabilities in approach then node is always `localhost` for me and each configuration is always unique to specific set of servers I deploy configuration to. So far we have just 2 different configuration files one for all servers which we share and another one specific to server role, so we apply one after another which is not workable in some scenarios where settings are conflicting in later stage for example.

I agree. A lot of the examples out there involve building infrastructure, setting IP addresses, etc… But I think you should be able to use config data to do what you need. I’m not at a computer right now so I can’t give you any examples. But your scenario is very similar to ours. We’re deploying DSC with Octopus Deploy as well using generic configurations that apply to multiple servers depending on their role. We build our MOF files ahead of time and just use Octopus to deliver them to nodes. Once I get back to a computer I can probably expand on this some more if you want and maybe find you a good example.

This video does go over using configuration data to build your MOF. I was told the example was a little too complicated but maybe it will help.


If you want, we could take this offline to discuss as well.

Link is dead (server is having hard time with MySQL), hope it will recover. So that video will explain how you to hierarchical DSC using Octopus deploy? We don’t compile MOF files instead we use localhost node and execute powershell script via Octopus command and then use variety of DSC cmdlets to verify if configuration is desired state. Intested to see what you go implemented so we will not make mistakes you might have made when starting. We are in very early stages of implementation.

That link should work now. The site was having issues that day. But it won’t explain how to do hierarchical DSC using Octopus. It’s just an intro to using Configuration Data with DSC. I’d be happy to take this offline and tell you a little bit about how we’re using Octopus Deploy with DSC though. I’ll PM you my contact info.

Thanks. Would like to know how it shall be done right from the get go.