DSC Composite Resources and optional variables

This topic contains 6 replies, has 2 voices, and was last updated by Profile photo of Justin King Justin King 11 months, 1 week ago.

  • Author
    Posts
  • #33448
    Profile photo of Justin King
    Justin King
    Participant

    Hi all,

    Possibly a simple syntax issue, but it seems like that no matter how I setup the parameters of a DSC composite resource, the primary configuration will return an error if a configuration node doesn't provide a value.

    For example, lets take a simple configuration:

    Configuration MasterConfig
    {
        Import-DscResource -Module Contoso_cCompositeConfiguration
        
        Node $AllNodes.NodeName {    
            cBase BaseConfig
            {
                DNSServerAddresses = $Node.DNSServerAddresses
                Location = $Node.Location
            }
        }
        

    Now in the said resource "cBase" I'll put in some base configs that are switched depending on the location, and allows me to input "override" DNS entries for things like DCs. straight forward so far:

    Configuration cBase
    {
        param (
            [Parameter(Mandatory=$false)][array]$DNSServerAddresses,
            [Parameter(Mandatory=$true)][ValidateNotNullorEmpty()][string]$Location
            )
        
        Import-DSCResource -ModuleName xNetworking
    
        If ($DNSServerAddresses) {
            xDNSServerAddress  DNSCustom {
                Address = $DNSServerAddresses
                InterfaceAlias = "Ethernet"
                AddressFamily = "IPV4"
                }
            }
    
        If (($Location -eq "Private") -and !($DNSServerAddresses)) {
            xDNSServerAddress  DNSPrivate {
                Address = "192.168.1.100","192.168.1.102"
                InterfaceAlias = "Ethernet"
                AddressFamily = "IPV4"
                }
            }
    }
    

    Now the "idea" is i can then drop in some configuraiton data and only _some_ of the nodes will actually have "DNSServerAddresses" defined, but when I do that, I fail to compile a mof and get an error message that a required parameter is missing.

    I've temporarily gotten around this by calling "cBase" (in this example) multiple times like this:

    Node $AllNodes.where{$_.DNSServerAddresses}.NodeName {    
            cBase BaseConfig
            {
                DNSServerAddresses = $Node.DNSServerAddresses
                Location =$Node.Location
            }
        }
        
        Node $AllNodes.where{!$_.DNSServerAddresses}.NodeName {    
            cBase BaseConfig
            {
                Location =$Node.Location
            }
        }
    

    .... but that feels like excessive amounts of coding and ... well ... I'm lazy.

    Is there a better way to structure this?

  • #33496
    Profile photo of Don Jones
    Don Jones
    Keymaster

    Well, but you've defined DNSServerAddress as mandatory, right? That'll cause a fail during the schema check if you haven't provided that value.

  • #33500
    Profile photo of Justin King
    Justin King
    Participant

    That sound you hear is my head as it collides with the desk...

    EDIT: OK I just looked at my _actual_ code to verify I didn't make that silly mistake ... I only did it in the fast example. I edited my original post to reflect that better.

    So to clarify, the cbase resource is NOT set to mandatory, but if i define it in the main configuration it will still error.

  • #33511
    Profile photo of Justin King
    Justin King
    Participant

    OK I"m re-reading your response Don, and it may be that I'm simply misunderstanding how the configuration works. Maybe you could clarify.

    When I do something like this in the configuration:

    cBase BaseConfig
            {
                DNSServerAddresses = $Node.DNSServerAddresses
                Location = $Node.Location
            }
    

    I thought I was merely defining which variables to pass to the resource. Does this statement actually make those variables mandatory because it checks for that value? Will it automatically pass variables to the resource that aren't called out in the configuration?

  • #33512
    Profile photo of Don Jones
    Don Jones
    Keymaster

    So, that example assumes DNSServerAddresses and Location are defined as parameters of the cBase resource. It's the Param() block in cBase, where you've put [Parameter(Mandatory=$True)] that makes them mandatory.

  • #33513
    Profile photo of Don Jones
    Don Jones
    Keymaster

    It might be helpful if you posted your actual cBase definition, at least the Param() block from it.

  • #33515
    Profile photo of Justin King
    Justin King
    Participant

    OK i went back to my real resource and imediately saw the error ... I'm returning to banging my head against the desk. For your enjoyment:

    [Parameter(Mandatory=$false)][ValidateNotNullorEmpty()][array]$DNSServerAddresses,

    Yeah .... Mandatory is false .... then I say validate not null or empty ... sigh ....

    You win! I clearly need to walk away from the keyboard now ...

You must be logged in to reply to this topic.