Invoking PowerShell DSC Resources directly

PowerShell Desired State Configuration (DSC) is a distributed Configuration Management (CM) platform which delivers a uniform way to configure Windows components.  Configuration Management tools should layer on top of DSC and components in the Windows server ecosystem should write DSC providers to ensure that customers can choose any CM tool they want and be confident that it will be able to configure every resource they use.  Just as you don’t investigate what printers a word processor supports before you buy it, you shouldn’t have to check what resources a CM tool supports before you buy it.  That is why we build platforms and why you should verify that anything you buy supports the platform.

 

In the past, the only way to use these DSC resources was by writing a full DSC Configuration for the entire system and applying it using Start-DscConfiguration.  This is a great mechanism and provides a very rich set of platform features which dramatically decrease the work and effort to build a new Configuration Management (CM) solution.  But while working closely with existing Configuration Management (CM) tool vendors, they indicated that they would like finer control over which parts of the platform they used.  That is why we introduced new functionality in the WMF 5.0 Preview February 2015 that allows you to call DSC resources directly. You can access DSC resource methods directly either using the new Invoke-DscResource cmdlet or using CIM/WSMAN if you want to do this from non-Windows systems.

 

Invoke-DscResource Cmdlet Syntax



        ·         Name:          Friendly name of the DSC Resource.

        ·         Method:       DSC Resource method name to be invoked. Possible values are Get/Set/Test.

        ·         Property:     DSC Resource method arguments name and value in form of hashtable.

        ·         Module:       Optional parameter that can be used to pass the module name of the DSC Resource.

 

How can I make sure that DSC LCM doesn’t interfere with my configuration management tool?

When a 3rd party tool is running, you don’t want the DSC LCM to conflict with its consistency equivalent operations or document processing so before calling any DSC resources, you have to change RefreshMode LCM setting. We have introduced an additional RefreshMode LCM setting in WMF February preview called ‘Disabled’. When RefreshMode is set to ‘Disabled’ mode, DSC doesn’t process any documents, run consistency checks, pull any configurations from the pull server or send reports to the report server.

 

In order to set this for your target node, we will create a new meta-configuration and apply it to the node where our 3rd party tool will be managing configuration.

 

[DscLocalConfigurationManager()]

Configuration LCMSettings {

    Node localhost

    {

        Settings

        {

            RefreshMode = “Disabled”

        }

    }

}

LCMSettings

Set-DscLocalConfigurationManager -Path .\LCMSettings -Verbose

 

 

When DSC is in ‘Disabled’ mode, you can only run ‘Invoke-DscResource’, ‘Set-DscLocalConfigurationManager’, ‘Get-DscLocalConfigurationManager’ and ‘Stop-DscConfiguration’ cmdlets. The rest of the DSC cmdlets will not work in this mode.

 

Here is an example of what you will see when you apply a configuration in ‘Disabled’ mode.

 

Start-DscConfiguration -Path .\DomainController -Wait -Verbose -Force

 

 

 

How can I utilize DSC resource methods in my 3rd party configuration management tool?

Let me explain first how DSC LCM would use these resource methods if it were still enabled. Understanding this will help you make decisions according to your management tool design and policies.

 

The DSC LCM reads the supplied document by Start-DscConfiguration, makes a list of the resources present in the document and then executes the list one by one. For each resource it checks whether the resource is in desired state or not by calling Test-TargetResource method. If Test-TargetResource returns false then it calls Set-TargetResource method to set the resource in desired state. LCM calls Get-TargetResource when you run Get-DscConfiguration to get the current state of the resource. The following example shows how you can achieve a similar set of actions using Invoke-DscResource.  

 

Example 1: Invoke DSC Resource methods from PowerShell

Here I am taking a simple example where you want to maintain a file and its contents on the system using the built-in file resource.

 

1.       Check whether the file is present or not on the system.

            # Test the resource state

            $destinationPath=$env:SystemDrive\DirectAccess.txt”;

            $fileContents=‘This file is create by Invoke-DscResource’

            $result = Invoke-DscResource -Name File -Method Test -Property @{

                                                DestinationPath=$destinationPath;

                                                Contents=$fileContents } -Verbose

            $result | fl * 

 

 

‘InDesiredState’ property in result shows the state of DSC resource. In this example ‘False’ means that the file is not present in the system.

2.       Let’s change the state of the resource, set it to desired state and create the file by calling ‘Set’ method.

$destinationPath=$env:SystemDrive\DirectAccess.txt”;

$fileContents=‘This file is create by Invoke-DscResource’

 

$result = Invoke-DscResource -Name File -Method Set -Property @{

                                                                DestinationPath=$destinationPath;

                                                                Contents=$fileContents } -Verbose

$result | fl * 

 

 

‘RebootRequired’ property in result, tells you whether reboot is required or not to complete the operation.

I don’t want to manage reboot from my management configuration script, Can Invoke-DscResource reboot the machine whenever required?

Invoke-DscResource works according to the LCM settings. You can change ‘RebootNodeIfNeeded’ to $true if you want Invoke-DscConfiguration to reboot the machine automatically otherwise set it to $false so that it can notify you by ‘RebootRequired’ in result.

3.       Use ‘Get’ DSC Resource method to see the current state of the resource?

$destinationPath=$env:SystemDrive\DirectAccess.txt”;

$fileContents=‘This file is create by Invoke-DscResource’

 

$result = Invoke-DscResource -Name File -Method Get -Property @{

                                                                DestinationPath=$destinationPath;

                                                                Contents=$fileContents } -Verbose

$result.ItemValue | fl * 

 

 

 

Example 2: Invoke DSC Resource methods using CIM and WSMAN:

 

The new Invoke-DscResource cmdlet makes accessing resources very simple but that doesn’t help you if you want to do this from a CM tool running on a Linux machine.  In these cases, you can use the CIM methods ResourceGet, ResourceSet, and ResourceTest from the MSFT_DscLocalConfigurationManager class to invoke resource methods directly.  The specifics of how you do this will vary based upon the programming language and WSMAN (WINRM) library that you use so what we’ll do is describe how it works and then show you how to do it using PowerShell’s CIM cmdlets and you can do the translation into your environment.

 

Invoke-DscResource creates an in-memory configuration document (MOF) and then passes the document to these CIM methods. If you choose to call these CIM methods directly, you will have to create the MOF document to pass to the CIM methods.

 

In the following example, I have a DSC document stored on the file system that contains the desired state of a txt file using the File resource.

 

DSC document ‘C:\FileResource.mof’ contents:

                instance of MSFT_FileDirectoryConfiguration

                {

                ResourceID = “[File]file”;

                Contents = “This file is create by Invoke-DscResource”;

                DestinationPath = “C:\\DirectAccess.txt”;

                ModuleName = “PSDesiredStateConfiguration”;

                SourceInfo = “::3::5::File”;

                ModuleVersion = “1.0”;

                ConfigurationName = “DirectAccess”;

                };

                instance of OMI_ConfigurationDocument

                {

                Version=”2.0.0″;

                MinimumCompatibleVersion = “1.0.0”;

                };

 

 

Invoke ‘ResourceTest’ method using Invoke-CimMethod cmdlet.

 

Please note: In the following example I am using Invoke-CimMethod cmdlet using WSMAN protocol, you will have to implement equivalent code compatible to your non-windows client machine.

 

$Namespace  = ‘root/Microsoft/Windows/DesiredStateConfiguration’

$ClassName  = ‘MSFT_DSCLocalConfigurationManager’

$cimClass   = Get-CimClass -Namespace $Namespace -ClassName $ClassName

 

$mofData = Get-Content $env:SystemDrive\FileResource.mof”

$enc = [system.Text.Encoding]::UTF8

$totalSize = [System.BitConverter]::GetBytes($mofData.Length + 4)

$dataInUint8Format = $totalSize + $enc.GetBytes($mofData)

 

$param = @{

    ModuleName       = ‘PSDesiredStateConfiguration’;

    resourceProperty = $dataInUint8Format;

    ResourceType     = ‘MSFT_FileDirectoryConfiguration’;

}

 

# Create Cim session

$wsmanSession = New-CimSession -ComputerName localhost -SessionOption (New-CimSessionOption -Protocol Wsman)

 

# Invoke DSC Resource Test method

Invoke-CimMethod -CimClass $cimClass -MethodName ResourceTest -Arguments $param -Verbose -CimSession $wsmanSession

 

 

 

In this blog I described two methods you can use to invoke a DSC resource method directly from your 3rd party configuration tool and described the new LCM RefreshMode value of ‘Disabled’.

 

You can find detailed information about DSC Resources in A walkthrough writing a DSC resource and LCM Settings in Understanding Meta Configuration in Windows PowerShell Desired State Configuration blog.

 

I hope you enjoyed reading this blog.

 

We greatly appreciate any and all feedback that we receive from our users – do please let us know what you think about this cmdlet.

 

Amit Saraf

Windows PowerShell Developer
Microsoft Corporation