Conditional execution of DSC resources

Hello,

I have been trying to figure out a nice way to conditionally execute my DSC resources based on Configuration parameters.

Node ('localhost')
{
        # Create a Web Application Pool
        
        xWebAppPool NewWebAppPool
        {
            Name = $siteName
            Ensure = "Present"
            #identityType = 'ApplicationPoolIdentity'
            identityType = 'SpecificUser'
            Credential = $appPoolID
        }
}

Here in the above configuration, I want to add a new app pool either with ApplicationPoolIdentity or CustomIdentity depending upon parameters in my Configuration section.

Any help ideas or pointers are appreciated.

Thanks

In this case, you’d probably just have a parameter for your configuration (or something in your ConfigurationData table) containing the identity type, and pass that variable on to the resource:

Configuration Demo
{
    param (
        [ValidateSet('ApplicationPoolIdentity', 'LocalService', 'LocalSystem', 'NetworkService', 'SpecificUser')]
        [string] $IdentityType = 'ApplicationPoolIdentity'
    )

    Import-DscResource -ModuleName xWebAdministration

    node localhost
    {
        xWebAppPool NewWebAppPool
        {
            Name         = $siteName
            Ensure       = 'Present'
            IdentityType = $IdentityType
            Credential   = $appPoolID
        }
    }
}

Or separate the configuration data outside of the configuration script.

https://msdn.microsoft.com/en-us/powershell/dsc/configdata

Just be careful using that guide for Config PSD1’s if you’re also going to use Import-PowerShellDataFile.

Having the commas splitting each hashtable in AllNodes, ends up putting them into an array, within the first element of the AllNodes array, which isn’t ideal.

I found it when starting to use the import function as the behaviour was strange.

Just a heads up

Thanks for your response.

In that case, how can I conditionally define webpool properties? For instance, if parameter value equals SpecificUser then ONLY define Credential property. And this type of conditions are more than 1 in number.

Appreciate your help.

That’s awkward for the moment. If you were calling a cmdlet, I would just tell you to use splatting, but unfortunately, the parser doesn’t allow for splatting to DSC resources. So you’ll need some duplication in your code, and an IF statement:

Configuration Demo
{
    param (
        [ValidateSet('ApplicationPoolIdentity', 'LocalService', 'LocalSystem', 'NetworkService', 'SpecificUser')]
        [string] $IdentityType = 'ApplicationPoolIdentity',

        [pscredential] $AppPoolID
    )

    Import-DscResource -ModuleName xWebAdministration

    node localhost
    {
        if ($IdentityType -eq 'SpecificUser')
        {
            xWebAppPool NewWebAppPool
            {
                Name         = $siteName
                Ensure       = 'Present'
                IdentityType = $IdentityType
                Credential   = $appPoolID
            }
        }
        else
        {
            xWebAppPool NewWebAppPool
            {
                Name         = $siteName
                Ensure       = 'Present'
                IdentityType = $IdentityType
            }
        }
    }
}

Incidentally, this can be a good place to use a composite resource to hide that duplication / complexity. The same code will exist, but you can hide it in another psm1 file.

This sounds a cleaner approach. Let me read about composite resources and see how can I use them in this scenario.
Thanks for the pointer. Will share my output and thoughts soon.

Bummer, this poops out on target machine due to unavailability of ‘xWebAdministration’ module. Can I automate the installation of this module (somehow wrap in my configuration)? Meaning if the module is installed on target machine then great else install it from PS gallery.
Thanks for your help!

Easiest way to handle that is to use a DSC pull server. In PSv5, you can use a pull server to distribute resource modules even if you’re using Start-DscConfiguration to push out the configs themselves.

If you don’t want to use a pull server, then you’ll have to get the modules onto the target system yourself in some other way.

“Easiest” is a relative term :slight_smile:

I just changed the $env:PSMoudlePath on that node to also point to a network share where I placed all the modules in advance.

Yes its easier but has its downsize in terms of security and increased cmdlets scan time.

You can automate the distribution of the module but not from the same configuration scripts that needs it, so in a two step method.