I wanted to take some time and do a write-up on creating a custom Desired State Configuration (DSC) resource using PowerShell v5 Classes.
PowerShell V5 Classes allow us to define a Class in similar fashion to C#. This is important for a few reasons. One of the first reasons that comes to mind is that it allows Developers with experience with any C based language to use concepts they already understand to work with PowerShell. From a developers perspective this reduces the complexity of learning PowerShell and extends it’s usability.
In reverse, PowerShell Classes help Ops guys extend their knowledge into the Developer world by gaining an understanding of Classes in C#.
I can say from experience, DSC Class based resources may appear to be confusing and scary at first however after you get the syntax down and understand the in’s and out’s it is far faster and simpler to work with.
So let’s get started breaking this down.
We will start off with a template that I use every time I want to go about creating a Custom Resource (or module). The code for this post is also in a example GitHub Repository which can be found at the bottom of this post.
I’ve called our Class (which is also our resource) ‘cService’. This resource (as the name suggests) allows you to start or stop a specific Windows service. Here is our base template we can start off with.
Here we have a simple template we can use to define our resource moving forward. You can see that we have an Enum at the top which contains two members, Absent and Present. An Enum is a great way to hold various different members that can be used in any PowerShell Class. After that we have a pretty much recognizable block of code which will feel similar to writing a script based DSC resource.
A couple of the major stand out differences here are the use of this ‘[DSCResource()]’ and ‘[DSCProperty()]’ tag. These two tags simply do as you would expect by helping outline resources and properties.
Moving down from that we have the Set, Test and Get. The difference here is that the Set, Test and Get are not functions like traditional Script based DSC resources these are now Method’s of our Class resource.
Another one of the differences here is that we are defining our return types for our Set, Test and Get methods. As you can imagine when we call our set method we don’t want to return anything. To return no data from the method we simply use the ‘Void’ datatype.
Of course, with our Test method we want to return a Boolean, being either True or False. Then we have our Get method. Get returns the datatype which is defined by our DSC Resource. Simply put, when we call Get we want to return an object of the type of our Class based resource (in this case cService).
You’ll notice if you copy and paste this (GitHub link at bottom) into the ISE you’ll get some red squiggles in the Test and Get. One of the other benefits of using a Class based DSC resource is that you get on the fly error/syntax checking. We can fix these by adding in some content to our resource.
Let’s start with our Get method.
So you might be saying right away. “Okay what is up with the ‘this’ variable“.
Well a simple way to think of this is: Anytime you need to reference a property ([DscProperty()]) from inside a method you will need to reference it using the $this variable.
Its important to note that the keyword return is mandatory in the Test and Get method. If you take away the return statement you will notice your method will have a red underline suggesting you include at least one.
Moving along to our Test method.
Here we have a basic Test method which will call the Set method if the outcome returns false. For the sake of this example we will simply return false if Ensure is Absent.
Let’s move onto the Set Method.
Everything within the Set, Test and Get should look familiar for anyone who has written even the most basic script based DSC Resource/Module. That’s really the point to hit home with this post. PowerShell V5 Classes and DSC Class based resources are super simple once you give it ago yourself.
Ok now we have our whole resource with our three methods ready to go. Let’s save this file as cService.psm1 into a folder called cService in the modules path of ‘C:\Program Files\WindowsPowerShell\Modules\cService’
We also need to create a Module Manifest to go along with our Module file. This will define the properties of our Module and contain some information about the author and the modules intent.
As an example. To generate the same one I used for this example here is the line of code.
Let’s take a look at the folder structure that contains the files we’ve just created.
Using Class based DSC resources makes our folder structure much more simplistic. Once we’ve got our files in the right place we’re ready to create a configuration with our new Module. Let’s give that a go now.
Once recreated and passed to the LCM we can see that all is working as intended.
Hopefully this post has helped shed some light on DSC Class based resources. There are a few other benefits of using Classes when creating DSC resources which you can read more about over here.
I’ve also put this example on my GitHub in hopes that it may help you out. The Repo can be found here.