Robert Westerlund

A developer's blog on code, technology and tools in the Web, .NET and other development areas.

NAVIGATION - SEARCH

Creating a Composite DSC Configuration with Parameters

While answering a question on StackOverflow I realized that I wanted to write a longer guide on the matter, which might not be a good fit for the Question and Answer format of StackOverflow. So, why not make a blog post of it?

The question was about how to create a composite Desired State Configuration (DSC) resource which has parameters. It might be valuable to know that I'm no expert on Desired State Configuration and tried many different things before I tried one that works. There might be other ways to achieve the goal, but this is a description of at least one way. In the examples, I will use BaseConfig for config name and MyParameter for parameter name.

Parameters to a Composite Configuration which is an ordinary module – not suggested

When a Composite Configuration is created as an ordinary module (directly in the C:\Program Files\WindowsPowerShell\Modules\MyModuleName, for example), it seems like it behaves like an ordinary Cmdlet. This means, to pass parameters to the composite configuration I had to do:

Import-DscResource -ModuleName BaseConfig 

Node localhost 
{ 
    BaseConfig Common -MyParameter "My Parameter Value" 
    { 
    } 
}

Worth noting is that I don't know if this would behave as expected for a DSC resource in other matters or not.

Also, if you create your composite configuration as a base module instead of a DSCResource within a module you will have to explicitly import the module since DSC won't do it automatically for you.

A Composite Configuration which supports parameters the right way

Since C:\Program Files\WindowsPowerShell\Modules is a long path and also is the folder in which we will should create our composite resource for it to be available for all users, I will shorten the path in the scripts below to display as C:\...\Modules and then subfolders are displayed as they are normally

In order to create a composite configuration which supports parameters, I had to make a dummy container module. These could, of course, contain implementation, but I only created an empty psm1 file and a psd1 file pointing to that psm1 file, using the following commands.

PS C:\...\Modules> md MyDscResources
PS C:\...\Modules> cd .\MyDscResources
PS C:\...\Modules\MyDscResources> "" > MyDscResources.psm1
PS C:\...\Modules\MyDscResources> New-ModuleManifest -Path .\MyDscResources.psd1 -RootModule MyDscResources.psm1

After making the empty container module, create a DSC resource folder (the name of the folder must be DSCResources) and then a folder for the composite configuration.

PS C:\...\Modules\MyDscResources> md DSCResources
PS C:\...\Modules\MyDscResources> cd .\DSCResources
PS C:\...\Modules\MyDscResources\DSCResources> md BaseConfig
PS C:\...\Modules\MyDscResources\DSCResources> cd .\BaseConfig

When we have the folder for our DSC Resource Composite Configuration, we should create the .schema.psm1 file, which should contain the composite configuration, as well as a .psd1 file which points to the module file. Note that the .schema.psm1 part of the filename must be matched exactly, since the PSDesiredStateConfiguration module actually looks specifically for this hard coded file extension for composite resources. Enter the following script into the BaseConfig.schema.psm1 file:

Configuration BaseConfig
{
    PARAM (
        $FileContents
    )
    
    File RootFile1
    {
        DestinationPath = "C:\FileAtRoot1.txt"
        Ensure = "Present"
        Contents = $FileContents
    }
    File RootFile2
    {
        DestinationPath = "C:\FileAtRoot2.txt"
        Ensure = "Present"
        Contents = $FileContents
    }
}

Then create a module manifest for the composite configuration:

PS C:\...\Modules\MyDscResources\DSCResources\BaseConfig> New-ModuleManifest -Path .\BaseConfig.psd1 -RootModule BaseConfig.schema.psm1

That's all which is needed to create the composite configuration.

Test the Composite Configuration

In order to test that our composite configuration works as expected, we need to create a configuration which uses the composite configuration we have created. The folder location is no longer important, so let's create the configuration in a C:\temp folder

PS C:\Program Files\WindowsPowerShell\Modules\MyDscResources\DSCResources\BaseConfig> cd\
PS C:\> md temp
PS C:\> cd temp
PS C:\temp> notepad ConfigurationTest.ps1

Into this ConfigurationTest.ps1 file, enter the following script:

Configuration ConfigurationTest
{
    Import-DscResource -Name BaseConfig
    
    Node localhost
    {
        BaseConfig Commoon
        {
            FileContents = "This is the file contents we want"
        }
    }
}

ConfigurationTest

Now that we have our composite configuration and also a configuration which uses this, let's execute the configuration script to create the MOF files and then use the Start-DscConfiguration cmdlet to let DSC execute the configuration:

PS C:\temp> .\ConfigurationTest.ps1
PS C:\temp> Start-DscConfiguration ConfigurationTest

Once DSC has completed executing the configuration we should have the expected files, C:\FileAtRoot1.txt and \FileAtRoot2.txt which both have the parameter value as contents.

Add comment