Author Posts

September 5, 2014 at 9:11 am

My question is about the scope in features. In this situation why is Name = NULL when $node.Feature can be found for the name of the feature as can cluster and node name.

configuration netserverWindowsFeatures
{ 
    $AllNodes = @(
        @{  NodeName = "dscw2k8";
            Cluster = "SERVERX";
            Feature =  "NET-Framework-Core"
        }
     )

    Node $AllNodes.Where{$_.Cluster -eq "SERVERX"}.NodeName
    {
        WindowsFeature $node.Feature
        {
            Name = $node.Feature
            Ensure = "Present"
        }
    } 
}
 
netserverWindowsFeatures

But in this situation name is equal to the name of the feature:

$configdata = @{
 
    AllNodes = @(
        @{  NodeName = "dscw2k8";
            Cluster = "SERVERX";
            Feature =  "NET-Framework-Core"
        }
     )
}
 
 
configuration netserverWindowsFeatures
{ 
    Node $AllNodes.Where{$_.Cluster -eq "SERVERX"}.NodeName
    {
        WindowsFeature $node.Feature
        {
            Name = $node.Feature
            Ensure = "Present"
        }
    } 
}
 
netserverWindowsFeatures  -ConfigurationData $configdata

I can't see why one works and the other doesn't it would be interesting to know why, thank you.
Also how does PowerShell know that $node is even a member of the array $AllNodes in the first place?

September 5, 2014 at 12:52 pm

I imagine because the AllNodes array is set in some way by PowerShell when passed as the ConfigurationData parameter that you can't override it within your configuration. Or, when PowerShell parses your configuration block to turn it into a .mof file, that it will only replace $AllNodes with what gets passed in via the ConfigurationData parameter. Remember, configuration blocks are a form of Domain-Specific Language (DSL) built-in to PowerShell. Although it looks like standard PowerShell, it doesn't behave like it all the time.

For example,

configuration YouCanNotLoadMe
{
    Import-DscResource -ModuleName FooledYouIDoNotExist -Name IDoNotExistEither
}

If you dot-source the file above into PowerShell, you'll get a compilation error because the FooledYouIDoNotExist module doesn't exist. In typical PowerShell, you wouldn't get an error about importing a missing module until you actually tried to execute it.

So, configuration blocks, though they look normal, aren't.

September 5, 2014 at 4:55 pm

If you're interested, you can see how quite a bit of DSC's MOF compilation code works by looking at the PSDesiredStateConfiguration.psm1 file under c:\windows\system32\WindowsPowerShell\v1.0\Modules\PSDesiredStateConfiguration\ . In this case, the automatic Node variable is based on $script:ConfigurationData (which is only set when you pass in a value for the -ConfigurationData parameter):

$nodeDataMap = @{}

if($script:ConfigurationData)
{
    $script:ConfigurationData.AllNodes | foreach { $nodeDataMap[$_.NodeName] = $_ }
}

# . . . [snip]

New-Object PSVariable ("Node", $nodeDataMap[$node])

Even if you were to have created a variable named $ConfigurationData instead of $AllNodes, it still wouldn't have worked, because the DSC module would not have set that value at the DSC module's script scope.

September 8, 2014 at 9:29 am

Thanks guys, that was really helpful. I've got it now. This http://technet.microsoft.com/en-us/library/dn249925.aspx was also quite useful.