Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell DSC Composite Resources

Tags:

powershell

I have successfully create DSC Configurations and deployed them onto servers. As a next step, I tried to break apart the parts of the Configuration blocks that are common among servers into reusable sections, or in DSC parlance 'composite resources'. After a lot of researching I am still unable to use the composite resources, they are not listed when running 'Get-DSCResource'.

After looking through the 'Get-DSCResource' function, it seems to require a 'DSCResources' subfolder which the PowerShell.org ebook doesn't state but the PowerShell Blog does. The Get-DSCResources function calls Get-Module with the resource name (SimpleConfig in the example). Both don't account for Get-Module not 'seeing' the sub folders when there isn't a psd1 in the root folder (BaseConfiguration in the example). I adapted these approaches resulting in the example below, but that has not succeeded either.

I've looked at:

  • PowerShell Blog
  • PowerShell.org EBook
  • Steven Murawski's DSC Series
  • Steven Murawksi's DSC User Group Presentation

Example Config:

# $env:ProgramFiles\WindowsPowerShell\BaseConfiguration\BaseConfiguration.psd1
@{
    ModuleVersion = '1.0'
    GUID = '84f449fd-8f26-4bb9-908f-eb675c56b5d8'
    Author = 'James Pogran'
}

# $env:ProgramFiles\WindowsPowerShell\BaseConfiguration\DSCResoures\SimpleConfig\SimpleConfig.schema.psm1
Configuration SimpleConfig
{
    Log LogThis
    {
        Message = "Foo"
    }
}

# $env:ProgramFiles\WindowsPowerShell\BaseConfiguration\DSCResoures\SimpleConfig\SimpleConfig.psd1
RootModule = "SimpleConfig.schema.psm1"
like image 660
James Pogran Avatar asked Oct 01 '22 10:10

James Pogran


1 Answers

Update 2014-04-12

The original instructions in this answers work correctly, but it shows an incorrect way of creating composite resources which is the reason why the module needs to be explicitly imported before being able to use the composite configuration in the test configuration.

Composite configurations should be created as ordinary DSC resources in the DSCResources subfolder of a container module. This is mentioned in the answer to this StackOverflow question and I've also written a blog post on creating composite DSC configurations which take parameters, which gives detailed instructions on the correct approach.

I've kept the original answer, only with a strike-through, since I think it is still helpful. Also, given the below information, it should be pretty usuable as well.

The reason that the Import-Module call was needed is that only ordinary DSC resources are able to be loaded automatically. The composite configuration should be created in a subfolder of a container module MyContainerModule\DSCResources\BaseConfig. The psm1 file of the container module can be empty and the composite configuration can be exactly as the original answer states (The Ìmport-DscResource command use the Name parameter instead of the ModuleName parameter though, if you want to keep the BaseConfig name there).

Detailed steps on creating a composite DSC configuration

Below are the steps I performed when I created and verified a composite configuration called BaseConfig. I hope this helps serve as a guide for you.

For all the following steps, I had the PowerShell ISE running as administrator.

Create the folder to hold the module

PS C:\WINDOWS\system32> cd 'C:\Program Files\WindowsPowerShell\Modules'
PS C:\Program Files\WindowsPowerShell\Modules> md BaseConfig

    Directory: C:\Program Files\WindowsPowerShell\Modules

Mode                LastWriteTime     Length Name                                                                         
----                -------------     ------ ----                                                                         
d----        2014-03-04     23:45            BaseConfig                                                                   

PS C:\Program Files\WindowsPowerShell\Modules> cd .\BaseConfig
PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> 

Create the composite configuration file

Naming for this file must end with ".schema.psm1", since this is hard coded into the PowerShell DSC module, the code for which you can find in the folder C:\windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration.

PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> notepad BaseConfig.schema.psm1

Into the BaseConfig.schema.psm1 file, I entered the following configuration:

Configuration BaseConfig
{
    File TestFile1
    {
        DestinationPath = "C:\CompositeConfigurationCreatedTextFile1.txt";
        Contents = "File1Content";
    }
    File TestFile2
    {
        DestinationPath = "C:\CompositeConfigurationCreatedTextFile2.txt";
        Contents = "File2Content";
    }
}

Create the module manifest

Creating the module manifest is easy, just let PowerShell do it for you.

PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> New-ModuleManifest -Path .\BaseConfig.psd1 -RootModule BaseConfig.schema.psm1

Verify that the composite configuration is found by PowerShell

After this step, we should have the composite configuration finished. To verify that it can be found, try running the following command and verify the output:

PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> Import-Module BaseConfig
PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> Get-Command -CommandType Configuration

CommandType     Name                                               ModuleName                                             
-----------     ----                                               ----------                                             
Configuration   BaseConfig                                         BaseConfig 

Important Note: I found that if I tried to execute the test configuration (below) without importing the module first, it failed; it wasn't able to recognize BaseConfig. After importing the module, the test configuration worked perfectly fine. However, if I later open a new PowerShell session or run Remove-Module in the current PowerShell session (both ways ensures that the module isn't loaded in the current session) the configuration will work just fine. So it seems, for some reason, that it wouldn't find my newly created composite configuration until I had imported the module at least once.

Test the composite configuration

To test the composite configuration, create a configuration which configures the configuration on the node localhost, execute it and verify that the expected changes have been made. I have detailed my exact steps in doing this below.

Create the test configuration

To use the composite configuration I first created a configuration definition file with the path c:\temp\testconfiguration.ps1

PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> md c:\Temp

    Directory: C:\

Mode                LastWriteTime     Length Name                                                                         
----                -------------     ------ ----                                                                         
d----        2014-03-04     23:47            Temp                                                                         

PS C:\Program Files\WindowsPowerShell\Modules\BaseConfig> cd \temp
PS C:\temp> notepad testconfiguration.ps1

And I gave it the following content:

Configuration TestConfiguration
{
    Import-DscResource -ModuleName BaseConfig

    node localhost 
    {
        BaseConfig Common
        {
            # The created configuration did not have any parameters, thus no properties
        }
    }
}

TestConfiguration

Create the mof file(s)

Then, to create the mof-files, just execute the ps1-file

PS C:\temp> .\testconfiguration.ps1

    Directory: C:\temp\TestConfiguration

Mode                LastWriteTime     Length Name                                                                         
----                -------------     ------ ----                                                                         
-a---        2014-03-04     23:49       2266 localhost.mof  

Execute the DSC configuration

After this, I let DSC execute the configuration using the following command:

PS C:\temp> Start-DscConfiguration TestConfiguration

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
2      Job2            Configuratio... Running       True            localhost            Start-DscConfiguration...

Verify that the expected changes have been made

Finally, I verified that the composite configuration has been run by verifying the existence of the two files which is should create.

PS C:\temp> ls c:\ -Filter *.txt

    Directory: C:\

Mode                LastWriteTime     Length Name                                                                         
----                -------------     ------ ----                                                                         
-a---        2014-03-04     23:51         15 CompositeConfigurationCreatedTextFile1.txt                                   
-a---        2014-03-04     23:51         15 CompositeConfigurationCreatedTextFile2.txt    

like image 196
Robert Westerlund Avatar answered Oct 05 '22 10:10

Robert Westerlund