PowerShell DSC - how to pass configuration parameters to ScriptResources?

mclayton picture mclayton · Apr 28, 2014 · Viewed 19.6k times · Source

I'm having a lot of trouble trying to get a PowerShell Desired State Configuration script working to configure an in-house application. The root of the problem is that I can't seem to pass my configuration data down into a ScriptResource (at least not with the way I'm trying to do it).

My script is supposed to create a config folder for our in-house application, and then write some settings into a file:

configuration MyApp {
    param (
        [string[]] $ComputerName = $env:ComputerName
    )
    node $ComputerName {

        File ConfigurationFolder {
            Type = "Directory"
            DestinationPath = $Node.ConfigFolder
            Ensure = "Present"
        }

        Script ConfigurationFile {
            SetScript = {
                write-verbose "running ConfigurationFile.SetScript";
                write-verbose "folder = $($Node.ConfigFolder)";
                write-verbose "filename = $($Node.ConfigFile)";
                [System.IO.File]::WriteAllText($Node.ConfigFile, "enabled=" + $Node.Enabled);
            }
            TestScript = {
                write-verbose "running ConfigurationFile.TestScript";
                write-verbose "folder = $($Node.ConfigFolder)";
                write-verbose "filename = $($Node.ConfigFile)";
                return (Test-Path $Node.ConfigFile);
            }
            GetScript = { @{Configured = (Test-Path $Node.ConfigFile)} }         
            DependsOn = "[File]ConfigurationFolder"
        }

    }
}

For reference, my configuration data looks like this:

$config = @{
    AllNodes = @(
        @{
            NodeName = "*"
            ConfigFolder = "C:\myapp\config"
            ConfigFile = "C:\myapp\config\config.txt"
        }
        @{
            NodeName = "ServerA"
            Enabled = "true"
        }
        @{
            NodeName = "ServerB"
            Enabled = "false"
        }
    )
}

And I'm applying DSC with the following:

$mof = MyApp -ConfigurationData $config;
Start-DscConfiguration MyApp –Wait –Verbose;

When I apply this configuration it happily creates the folder, but fails to do anything with the config file. Looking at the output below, it's obvious that it's because the $Node variable is null inside the scope of ConfigurationFile / TestScript, but I've got no idea how to reference it from within that block.

LCM:  [ Start  Resource ]  [[Script]ConfigurationFile]
LCM:  [ Start  Test     ]  [[Script]ConfigurationFile]
                           [[Script]ConfigurationFile] running ConfigurationFile.TestScript
                           [[Script]ConfigurationFile] node is null = True
                           [[Script]ConfigurationFile] folder =
                           [[Script]ConfigurationFile] filename =
LCM:  [ End    Test     ]  [[Script]ConfigurationFile]  in 0.4850 seconds.

I've burnt off an entire day searching online for this specific problem, but all the examples of variables, parameters and configuration data all use File and Registry resources or other non-script resources, which I've already got working in the "ConfigurationFolder" block in my script. The thing I'm stuck on is how to reference the configuration data from within a Script resource like my "ConfigurationFile".

I've drawn a complete blank so any help would be greatly appreciated. If all else fails I may have to create a separate "configuration" script per server and hard-code the values, which I really don't want to do if at all possible.

Cheers,

Mike

Answer

Steve picture Steve · Jan 8, 2015

Change this: $Node.ConfigFolder to $using:Node.ConfigFolder.

If you have a variable called $Foo and you want it to be passed to a script DSC resource, then use $using:Foo