How to Deploy and Discover Windows PowerShell Desired State Configuration Resources

How to Deploy and Discover Windows PowerShell Desired State Configuration Resources

Rate This
  • Comments 7

A Windows PowerShell Desired State Configuration (DSC) resource contains a module file (*.psm1), an optional data file (*.psd1),and a *.schema.mof file. Details about what each of those files should look like, and how you can create those files using a DSC Resource Designer Tool, are discussed in an earlier blog post.  In this blog post, we will explore the following.

  1. How to deploy DSC resources to the local computer
  2. How to discover the resources deployed, while authoring a new configuration
  3. How to deploy resources to the pull server, and how the local configuration manager (LCM) locates the required resources on the pull server.

Deploying DSC resources to the local computer

All DSC resources should be deployed in the following folder hierarchy:-

            $env: psmodulepath (folder)

                        |- <ModuleName> (folder)

                                    |-  <ModuleName.psd1> (file,required)

                                    |- DSCResources (folder)

                                                |- <DSCResourceName1> (folder)

                                                            |- <DSCResourceName1.psd1> (file, optional)

                                                            |- <DSCResourceName1.psm1> (file, required)

                                                            |- <DSCResourceName1.schema.mof> (file, required)

                                                |- <DSCResourceName2>(folder)

                                                             |- <DSCResourceName2.psd1> (file, optional)

                                                             |- <DSCResourceName2.psm1> (file, required)

                                                             |- <DSCResourceName2.schema.mof> (file, required)          

                      

Example:  Suppose the Hyper-V team decided to add a resource named VM in to their existing PowerShell module under $pshome, Then the folder structure of their DSC resource would look like the following.

 

C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Hyper-V\DSCResources\VM\                                                                                     -VM.psd1(optional)                                                                                                                                                            -VM.psm1                                                                                                                                                                   -VM.Schema.mof

 

Usually, the environment variable $env:psmodulePath contains more than one path, and you can deploy DSC resources in any one of the paths. But there are some subtle differences during authoring or applying configuration to the system. Because LCM runs in System context, applying a configuration fails if your resources module are not in the $pshome or $env:ProgramFiles folder. The differences in the authoring experience are discussed in this post, in the Import-DSCResources section.

How to use and discover DSC resources

The number of PowerShell modules and cmdlets are increasing in every PowerShell release, hence increasing the number of results returned by Get-Module and Get-Command.  To keep those cmdlets useful, DSC resources have been stored in a subfolder of a main PowerShell module folder.

 

Because DSC Resources are not deployed directly under $env: psmodulepath, they cannot be discovered by running the Get-Module -List Available cmdlet. Get-Command for the GET/SET/TEST method of the resources will fail. Also, you can’t import the DSC resource with a partial name, as shown in the following examples.

Let us try to find MSFT_EnvironmentResource, one of the DSC resources which is shipped with PowerShell 4.0.

 

Get-Module MSFT_EnvironmentResource –ListAvailable   # Empty result (module not found)

Get-Command Get-TargetResource # Error: Command not found exception.

Import-Module MSFT_EnvironmentResource # Error: ModuleNotFound

 

You can, however, import the module by using its full path, like any PowerShell module, and call its GET/SET/TEST methods.

Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\DSCResources\MSFT_EnvironmentResource # Works

 

There are two new cmdlets that are added in PowerShell 4.0 to help discover DSC resources.

 

Get-DscResource: Gets all the DSC resources. You can pass a resource name list to filter the result.

                    Example:-Get-DscResource Env*ment, Windows*, Log   ß Returns all the resources that match the specified criteria.

So one way to test if your resources are deployed correctly is to see if they are being discovered by Get-DscResource.

 

Import-DscResource:  Import-DScResource is a dynamic keyword which can only be used inside a Configuration script block. When you are authoring a new configuration, you must import the resources needed by your configuration using this cmdlet. But if your DSC resources are stored in $pshome, you don’t need to explicitly import them. They are automatically loaded by PowerShell.

The signature of the cmdlet is shown below.

Import-DscResource [-Name <ResourceName(s)>] [-ModuleName <ModuleName(s)>]

Name:  This is the DSC resource name(s) that you must import. If the module name is specified, the command searches for these DSC resources within this module; otherwise the command searches the DSC resources in all DSC resource paths.

ModuleName:  This is the container module name(s), or module specification(s).  If the DSC resources that are required are specified, the command will try to import only those resources from the module(s).; Otherwise, the command imports all  the DSC resources in this module.

You can specify either one or both Name and ModuleName parameters in the cmdlet. But you must explicitly pass pairs of the parameter name and its value. Positional parameters are not supported.

            Import-DscResource is a second way to make sure your resources are deployed correctly.

Example:-

Configuration MSDSCConfiguration  {

                                       

Import-DSCResource -ModuleName MS_DSC1 -name Resource1, Resource2, Resource3

# Search for and imports Resource1 Resource2, and Resource3 inside the modules MS_DSC1

Import-DSCResource -Name Resource1 

# Search DSC resources for Resource1 under all valid DSC resource paths, and import the

# resource. Note that this will run slower because it has to search the resource in all the

# valid DSC resource folders. 

Import-DSCResource -ModuleName MS_DSC1

# Search for and import all DSC resources inside the module MS_DSC1. 

  ...

}

Deploying DSC resources to the pull server

After you configure your pull server [For details about how to configure a pull server, and how a pull client works, see this blog post]. DSC resources can be packaged and placed in the pull server resource repository for pull clients to download it. The folder hierarchy of the pull server DSC Resource repository should be the following. 

$env:ProgramFiles\WindowsPowerShell\DscService\Modules\  (folder)                                                                                        ModuleName_Version.zip                                                                                                             ModuleName_Version.zip.checksum 

When it’s unzipped, ModuleName_Version.zip should have the same folder structure as the local computer deployment hierarchy shown at the beginning of this blog post.

  • The Version is the version of the module, not the version of the DSC resource. Versioning works at the module level, not the DSC resource level.
  • ModuleName_Version.zip. Checksum is a checksum of the zip file generated by running the following  command.

New-DSCCheckSum –path $env:ProgramFiles\WindowsPowerShell\DscService\Modules\ -force

 

A configuration stored in the pull server configuration repository that requires the preceding module must refer to the module as follows.

 

instance of <ResourceName>

{

….  

ModuleName = "<ModuleName>";

ModuleVersion = “<Version>"; 

};

 

After LCM downloads a configuration from the pull server, it checks if the resources needed by the configuration exists on the local machine. If it does not exist, LCM queries the Download Manager of the local machine to download the required module, by specifying the ModuleName and ModuleVersion. After the module is downloaded and verified, it is saved to the $env: ProgramFiles\WindowsPowershell\Modules\ folder, and the configuration is applied by calling the TEST and SET methods of each resources.

 

 Updated on 7/17/2014:- <ModuleName.psd1> is required file inside the PowerShell module. The folder hierarchy in the blog post have been updated accordingly.

 

Berhe Abrha

PowerShell Team

Leave a Comment
  • Please add 1 and 5 and type the answer here:
  • Post
  • Nice written. Thank you.

  • Thank you for sharing the steps about how to deploy DSC resources to the pull server. Hope the TechNet documentation will be updated later.

  • I'm trying to deploy a custom resource from my Pull Server hosted on 2008 R2 and each node I try to deploy to gives the error:

    "Invoke-CimMethod : Failed to extract the module from zip file

    C:\Windows\TEMP\\635290882531911299\NTFSPermission_1.0.zip downloaded by Download

    Manager WebDownloadManager."

    I get the same error if I use a file share and DSCFileDownload. Is there some piece of configuration that I'm missing? If I move the module over manually the configuration is able to complete successfully.

  • Hi I am using DSC in pull mode with the DSCFileDownloadManager option as opposed to the Web option. I have placed a custom module (zipped and checksum'd) in the root of the Pull Share (i.e alongside MOF files). However the client servers make no attempt to download the custom module when I specify the resource in my configurations. However, errors are generated when executing Invoke-CimMethod stating:

    Invoke-CimMethod : The PowerShell provider <ModuleName> does not exist at the PowerShell module path nor is it registered as a WMI provider.

    So clearly it knows that it requires the module, but for some reason it won't download it.

    Thanks.

  • Joel:  It looks like your module is downloaded but unzipping failed. Try manually unzipping your module and deploy it on your machine then push your configuration using start-dscconfiguration  -path .\ -force  if that works then I would like to know how you zip your files.

    Andy:  Make sure your source and destination path are passed correctly  on your MetaConfiguration. below is an example of valid meta-configuration

    instance of MSFT_KeyValuePair as $keyvaluepair1

    {

    key = "SourcePath";

           value = "C:\\SharePath\\PullModule";

    };

    instance of MSFT_KeyValuePair as $keyvaluepair2

    {

    key = "DestinationPath";

           value = "C:\\DestinationPath";

    };    

    instance of MSFT_DSCMetaConfiguration

    {

    ConfigurationID = "C1";

    RefreshMode="PULL";

    DownloadManagerName="DSCFileDownloadManager";

    DownloadManagerCustomData = {$keyvaluepair1,$keyvaluepair2};

    };

  • Modules published via Pull server need to be named <moduleName>.<moduleVersion>.zip, NOT <moduleName>_<moduleVersion>.zip

    Example:

    xSqlPs.1.0.zip

    xSqlPs.1.0.zip.checksum

    Please update your documentation.

  • Hi when processing the  xWebAdministration_1.3.2.zip I get the following error has anybody seen this before

    MSFT_xWebsite is either missing or its associated MOF schema C:\Program Files\WindowsPowerShell\Modules\xWebAdministration\DscResources\MSFT_xWebsite\MSFT_xWebsite.schema.mof is missing or invalid.

Page 1 of 1 (7 items)