Series: Desired State Configuration – Part 5 : Creating Custom Resources

In this post of the Desired State Configuration series we will look at creating new custom DSC Resource. If you are reading this post and have not read the precious blog post titled “Anatomy of DSC Resource”, I would highly recommend to read that first. It will provide you enough insight on what DSC resources are and the things to be taken care off while creating custom DSC resources.

We will be creating a new custom DSC resource related to Windows Firewall. Firewall is a feature of Windows providing rules that can be enabled and disabled. This custom resource is called “CheckFirewall” and would be responsible for managing the firewall rules i.e. enabling and disabling firewall rules.

The DSC resource would perform the following actions

  1. Check the value within Configuration and call the function Test-TargetResource.
  2. If the value is ‘Absent’, then return ‘True’ if firewall is not already enabled else return ‘False’.
  3. If the value is ‘Present’, then return ‘True’, if the firewall is already enabled else return ‘False’.
  4. If the value returned by Test-TargetResource is “False”, DSC would call “Set-TargetResource” function of the Resource whereas if the Test-TargetResource function returns “True”, DSC would call “Get-TargetResource” function of the resource.
  5. The “Set-TargetResource” function of the resource is generally responsible for checking each property of the target resource and update it according to the provided configuration. However, in our case, we are either enabling or disabling a firewall rule and hence would not be checking any properties provided by Firewall rules.

Create a Resource Provider Folder

Create a Folder called “CheckFirewall” at “<<Your Drive>>\Windows\System32\WindowsPowershell\v1.0\Modules\PSDesiredStateConfiguration\PsProviders\”. In my case the drive is C:\

5-1

Create MOF file

The first step in creating the Resource is to create its MOF file. For more details about MOF files, refer to earlier post.

We have named the MOF file as CheckFirewall.Schema.mof and the name of the class is CheckFirewall. Its version number is “1.0.0” and friendly name is also “CheckFirewall”.  Please note that it is this friendly name that is referred within the DSC configuration script. There are just 2 properties for this class

  1. DisplayName: referring to the display name of the firewall rule that needs to be enabled or disabled.
  2. Ensure: flag referring to whether the firewall rule should be enabled or disabled.

5-2

The MOF file can also be copied from some existing resource and modified as shown above and this is definitely more convenient and easier.

Create the Powershell Script Module file

In this step, we would create the script file that is the crux of creating the custom resource. The entire brains of the resource lies within this script file because it is here that all the DSC related mandatory functions are implemented namely Set-TargetResource, Get-TargetResource and Test-TargetResource.

Open Powershell ISE and implement the above mentioned three function and save it in CheckFirewall Directory created above as CheckFirewall.psm1 file.

We will use Windows Firewall Powershell cmdlets to determine the current state of the firewall rule and also for enabling and disabling it.

The Test-TargetResource function looks like below. We have used the Get-NetFirewallRule cmdlet for retrieving the details of firewall rule. The name of the firewall rule comes for the DSC configuration script as argument to this function.

5-3

The Get-TargetResource function looks like below. Again, we have used the Get-NetFirewallRule cmdlet for retrieving the details of firewall rule. The name of the firewall rule comes for the DSC configuration script as argument to this function. Here, we also check its current status to toggle the Ensure property.

5-41

The Set-TargetResource function looks like below. Again, we have used the Get-NetFirewallRule cmdlet for retrieving the details of firewall rule. The name of the firewall rule comes for the DSC configuration script as argument to this function. Here, we also check its current status to toggle the Ensure property.

5-5

Additionally, we also enable or disable the firewall rule using “Enable-NetFirewallRule” or “Disable-NetFirewallRule” depending upon the value of the configuration.

Above, notice that all the three functions defines parameters related to the properties available in the MOF file. Also, some can be mandatory while others could be optional.

Also, both Set-TargetResource and Get-TargetResource returns back a hashtable containing all the properties defined in the MOF file.

Generate the PSD1 file

We can either generate a new PSD1 file using “New-ModuleManifest” or copy some existing psd1 file for existing resource and modify accordingly. I recommend using the first approach of using the “New-ModuleManifest” since this would be less error prone provided you provide correct values. The details about generating this file is available in earlier blog post.

The name of the file should be “CheckFirewall” and should be generated within the above created folder. The sample content looks like below.

5-6

Now, this resource can be used in any DSC configuration script. An example is provided below. We have a Configuration node containing a Node for the Server name which in turn contains our new custom resource “CheckFirewall” and is named as “SQLFirewallPresent”. It is setting two available resource property i.e. DisplayName and Ensure. You would see that these are the two properties we have defined in our MOF file.

5-7

This concludes the creation of a custom resource for DSC. This is a simplified way of creating of DSC resource and many more aspects like localization and error handling should be part of the overall script.

Hope you liked this post.

Cheers!!!

Advertisements

Series: Desired State Configuration – Part 3 : Pushing Configuration to Targets

This is the third part of the Series on Desired State Configuration. In this part we will look at how to create a configuration and push the same to the target servers. In the part, we will look at steps for bringing a target server to the expected state using the configuration.

We will use the same configuration that we created during the first part of the series. For sake of recalling, adding the same Configuration script below.

p3-1

In the above Configuration script, I have the top level Configuration element named “EnableFeatures”. Within this parent node, I have two nodes namely “WIN-PETR4TD7LAA” and “SCR2i”. These are the two servers which I want bring them into expected state i.e. to enable “Web-Server” feature on “WIN-PETR4TD7LAA” and “XPS-Viewer” on “SCR2i”. Above within the server nodes we have resource type “WindowsFeature” named “web-server” and “XPS”. These names could be any name that logically identifies it. Name within the resource reflects the name of the resource that we want to either add/remove from the environment or change its existing state if already added. “Ensure” reflects whether the resource should be installed or uninstalled depending on its value i.e. “Present” or “Absent”.

I would reflect the initial state of both the server with regard to their windows features and Roles.

Within the above Configuration, Server WIN-PETR4TD7LAA should have “Web-Server” Feature/Role available as its desired state and Server SCR2i should have “XPS-Viewer” Feature/Role removed from the server if it is already available.

Below is the screenshot for the server “WIN-PETR4TD7LAA” where Web Server is not installed

p3-2

And the screenshot for the server “SCR2i” where XPS-Viewer is already installed.

p3-3

So far we were looking at the environment that needs to adhere to the expected Configuration and also looked at the Configuration that needs to be reflected on the target servers. Now, we will look at steps to make the magic happens i.e. to run the configuration on individual target servers and change their state based on the configuration.

Step 1: Create the Configuration File.

We have already created this step and do not need to do it again. We will use the above Configuration file.

Step 2: Save the Configuration File to an appropriate location on file system.

Within Powershell ISE, while the configuration script is visible, select Menu-> Save as and save the configuration as ps1 file on file system. In my case, I have stored the file at “C:\“.

p3-4

 Step 3: dot-source ps1 file and load it in current session.

This step will enable to load the Test.ps1 file and keep in its scope the configuration data and function. If we do not dot-source it, the configuration would be loaded and unloaded immediately and would not be available to use in subsequent steps.

p3-5

Step 4: Execute the Configuration

In last step we loaded the file containing the configuration script “EnableFeatures”. In this step, we will execute the same configuration “EnableFeatures” to generate the Management Object Format (MOF) files one for each server.

Executing a Configuration is similar to executing a cmdlet or calling a function. Just call it by its name!

p3-6

Executing the Configuration would result in creating of one MOF file for each server containing all of its related resource types and configuration like name, ensure etc. These MOF Files would be generated within a folder created by executing the above configuration. The name of the folder is same of that of the configuration.

Step 5: Push the Configuration to the target server and execute

 p3-7

Start-DscConfiguration is a Powershell cmdlet provided by the Desired State Configuration module installed with Powershell 4.0. This Cmdlet is responsible for pushing the configuration to the target machines.

-wait lets the Powershell host wait until the cmdlet has finished executing

-verbose provides detailed actions executed by desired state configuration engine.

-force is self-explanatory.

Below is the screenshot while DSC Engine is bringing the target machine according to its configuration file.

And below is the verbose output while executing the configuration through Start-DscConfiguration.

p3-9

Now, let’s check the result of executing the configuration.

p3-10

p3-11

Note: If you have different servers in your configuration either you can use the credentials property of individual resource or use the credential property of Start-DscConfiguration to run the configuration remotely.

In the next part, we will look into the anatomy of creating a new DSC resources.

Cheers!!