Wednesday, May 4, 2016

How to parameterize a basic DSC configuration

After reading my two previous posts (here and here) you should have a good understanding of how DSC Configurations work.

At this point, it may be useful to know that within a Configuration block you can use parameters just like you would do in Functions:

Configuration TestConfig
{
    Param (
 [string[]]$ComputerName
 )
    Node $Computername

    {
        WindowsFeature FileAndStorage
        {
            Name = 'FileAndStorage-Services'
            Ensure = 'Present'
        }
    }
}
The aim of this Configuration is to enable the File and Storage Services feature on a given node. If we query the help for it we get:

Man TestConfig -Parameter * | Format-Table Name,IsDynamic,Required,Position,Aliases

name              isDynamic required position aliases
----              --------- -------- -------- -------
ComputerName      false     false    4        None   
ConfigurationData false     false    3        None   
DependsOn         false     false    1        None   
InstanceName      false     false    0        None   
OutputPath        false     false    2        None
There are here four parameters that automatically come with the Configuration keyword plus one parameter that I explicitely define in the Param () section of the script: ComputerName.

Man TestConfig -Parameter ComputerName

-ComputerName 
    
    Required?                    false
    Position?                    4
    Accept pipeline input?       false
    Parameter set name           (All)
    Aliases                      None
    Dynamic?                     false
Running the Configuration will generate a MOF file for the server specified in $ComputerName:

TestConfig -ComputerName 'srv1'

WARNING: The configuration 'TestConfig' is loading one or more built-in resources without explicitly importing associated modules. Add Import-DscResource –ModuleName 'PSDesiredStateConfiguration' to your configuration to avoid this message.


    Directory: E:\dsc\TestConfig


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         5/4/2016  12:58 PM           1974 srv1.mof

We can pass more than one server to the ComputerName parameter and each will get its customized MOF file:

TestConfig -ComputerName 'srv1','srv2'
WARNING: The configuration 'TestConfig' is loading one or more built-in resources without explicitly importing associated modules. Add Import-DscResource –ModuleName 'PSDesiredStateConfiguration' to your configuration to avoid this message.


    Directory: E:\dsc\TestConfig


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         5/4/2016   1:00 PM           1974 srv1.mof
-a----         5/4/2016   1:00 PM           1962 srv2.mof
Inside each MOF you'll find a @TargetNode:

Get-Content .\TestConfig\* | Select-String Target

@TargetNode='srv1'
@TargetNode='srv2'
Let's try now to add a second parameter in the form of a Feature that we'd like to be installed on the target servers. Before we proceed, note here that the Name property of the WindowsFeature resource takes in the Name of the feature as it is returned by Get-WindowsFeature, not its Display Name otherwise you'll get a ugly red error when running Start-DscConfiguration:

PowerShell DSC resource MSFT_RoleResource  failed to execute Test-TargetResource functionality with error message: The requested feature File and Storage Services is not found on the target machine. 
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : ProviderOperationExecutionFailure
    + PSComputerName        : srv1
So, here's my Configuration block with two parameters:

Configuration TestConfig
{
    Param (
    [string[]]$ComputerName,
    [string]$Feature
    )
    Node $Computername

    {
        WindowsFeature $Feature
        {
            Name = $Feature
            Ensure = 'Present'
        }
    }
}

TestConfig -ComputerName 'srv1' -Feature 'FileAndStorage-Services'

    Directory: E:\dsc\TestConfig


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         5/4/2016   1:09 PM           1998 srv1.mof

That is working pretty cool!

Now if I want to have more than one service running, the question is: is it possible to do a foreach loop in the WindowsFeature block?

The answer is yes: just change the parameter type to String[] so that it can accept multiple values and add the foreach loop around the WindowsFeature bock.

Configuration TestConfig
{
    Param (
    [string[]]$ComputerName,
    [string[]]$Feature
    )
    Node $Computername

    {

    foreach($FeatureName in $Feature) {

        WindowsFeature $FeatureName

            {

            Name = $FeatureName

            }

    }
        
    }
}

TestConfig -ComputerName 'srv1','srv2' -Feature 'FileAndStorage-Services','FS-SMB1'

man TestConfig -Parameter * | Format-Table Name,parameterValue -auto

name              parameterValue
----              --------------
ComputerName      string[]      
ConfigurationData hashtable     
DependsOn         string[]      
Feature           string[]      
InstanceName      string        
OutputPath        string
That's a good achievement for today. Let me just finish this post beautyfing the output of this script and remove the orange warning:

WARNING: The configuration 'TestConfig' is loading one or more built-in resources without explicitly importing associated modules. Add Import-DscResource –ModuleName 'PSDesiredStateConfiguration' to your configuration to avoid this message.
To do so just add the Import-DscResource magic word between the Param () section and the Node keyword:


Feel free to share!

No comments:

Post a Comment

Related Posts Plugin for WordPress, Blogger...