DSC Feature Scope

This topic contains 3 replies, has 3 voices, and was last updated by Profile photo of John Bateman John Bateman 2 years, 3 months ago.

  • Author
    Posts
  • #18555
    Profile photo of John Bateman
    John Bateman
    Participant

    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?

  • #18566
    Profile photo of Aaron Jensen
    Aaron Jensen
    Participant

    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.

  • #18570
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    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.

  • #18629
    Profile photo of John Bateman
    John Bateman
    Participant

    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.

You must be logged in to reply to this topic.