PowerShell, Server administration

Creating a PowerShell DSC extension for your custom tasks

4 min read

Following my post on automating your mundane Azure Virtual Machine Windows provisioning tasks with PowerShell DSC, it may happen that you have custom tasks that you want to do that that are not already available on PowerShell gallery. You may also have custom complex logic that you want to reuse across many different DSC scripts that you would like to centralize. This is where extensions come into play. It allows you to create custom resource operations that you can use within your nodes provisioning.

There are a few ways to create extensions:

Today, I will show you how this can be done using the Resource Designer Tool exposed by the xDscResourceDesigner.

Setup

First thing is to import (or install) the xDscResourceDesigner module. you can do so by running the following:

Creating the module

The module will be created in the folder C:\Program Files\WindowsPowerShell\Modules. This will allow us to use the Import-DscResource -ModuleName <dscModuleName> statement as this path is in the paths contained in the environment variable used by PowerShell to resolve the modules, $env:PSModulePath.

The module needs a module manifest. A module manifest is a PowerShell data file (.psd1) that describes the contents of a module and determines how a module is processed1. The PowerShell snippet below does exactly that. It uses the New-ModuleManifest cmdlet. Remember that a module can have multiple individual resources in it.

In order to run the snippet below, you will need to open PowerShell in administrative mode, as it needs to write into the restricted folder C:\Program Files\WindowsPowerShell\Modules

Creating the resource

Now we want to create our HelloWorld resource. You can name it the way you want, but to respect the fact that this is an extension, I put an x before the resource name.

As you can see in the snippet above, we create 3 property parameters for our resource: Path, Content and Ensure. We also have an attribute on each of our property parameters. The attribute determines the type of parameter your property parameter will be. The possible values are:

  • Key: determines that this is the unique key to identify the resource
  • Required: determines that the property is required
  • Read: determines that the property is a readonly property
  • Write: determines that the property can written to, that is that it can be specified in the configuration

As mentioned, each resource needs a key property to uniquely identify the resource, in case you use it more than once in the same configuration. In the example above, the Path property is the key. We also have 2 write properties, that is Content and Ensure.

Final script

Adding some meat into the resource

Now that the module and the resource are created, it is time to add some logic in the xHelloWorld resource. If you navigate into the folder C:\Program Files\WindowsPowerShell\Modules\xHelloWorldPSDesiredStateConfiguration\DSCResources\xHelloWorld, you will find the file xHelloWorld.psm1. In it, you will see there’s 3 functions: Get-TargetResource, Set-TargetResource and Test-TargetResource. In each, you have some comments about what the function can return (or expects as a return value) and other useful information. If you remember, the Script resource has basically the same structure:

  • Get-TargetResource: a function that returns the current state of the Node
  • Set-TargetResource: a function that DSC uses to enforce compliance when the Node is not in the desired state
  • Test-TargetResource: a function that determines if the Node is in the desired state

So in each, you fill in the mandatory code to satisfy the above conditions. In our case, we could have the following in our 3 functions:

Get-TargetResource:

Test-TargetResource:

Set-TargetResource:

Testing and using the resource

To test the resource schema, there’s a cmdlet that is available to you called Test-xDscSchema. That cmdlet can be used to test the validity of a MOF schema that you have written manually. Call the Test-xDscSchema cmdlet, passing the path of a MOF resource schema as a parameter. The cmdlet will output any errors in the schema2.

To use the newly created resource, create a DSC configuration and import the module in which the resource lives in. In our case, it would be Import-DscResource -ModuleName xHelloWorldPSDesiredStateConfiguration. You can then use the resource operation in your Node configuration:

If you load the module into PowerShell (5.1), using Import-Module "C:\Program Files\WindowsPowerShell\Modules\xHelloWorldPSDesiredStateConfiguration\xHelloWorldPSDesiredStateConfiguration.psd1", you can verify that your DSCResource exists by running Get-DscResource -Module xHelloWorldPSDesiredStateConfiguration.

Get-DSCResource output

Updating the resource

If you want to make modifications to your resource down the road, such as adding a new parameter, you can do so by using the Update-xDscResource cmdlet. Assume we want to add a String property to the xHelloWorld resource called EndOfLineCharacter. We can do this with the following:

After adding the property parameter, do not forget to update your psm1 file to use your new parameter!

You will also want to update your module version. To do that, you can do:

Conclusion

As you can see, using the designer, it is easy to create a new DSCResource. If you are more of a C# person, definitely try out the other methods as mentioned above.

If you believe your modules and extensions can be of use to everyone else, but sure to publish them on PowerShell Gallery!

Happy DSC-ing!