Author Posts

July 17, 2014 at 9:36 pm

Does anyone have an example of how to use the $AllNodes.Foreach expression in the configuration data as I ve tried numerous attempts to get this to work with no success to date

thanks Glenn

July 18, 2014 at 6:11 am

Glenn –

Can you provide an example(s) of something you have tried? Have you tried using Where instead?

$ConfigData = @{
    AllNodes = @(
        @{
            NodeName = 'Localhost'
            Role = 'TargetPractice'
            DestinationPath = 'C:\Blah'
        },
        @{
            NodeName = 'ServerA'
            Role = 'FileServer'
            DestinationPath = 'C:\Scripts'
        }
    )
}

Configuration ScalableDSC {

    node $AllNodes.Where({$_.Role -Like 'TargetPractice'}).NodeName {

        File Scripts
        {
            SourcePath = "\\Server\Scripts"
            DestinationPath = $Node.DestinationPath
            Ensure = "Present"

        }

    }

    node $AllNodes.Where({$_.Role -Like 'FileServer'}).NodeName {

        File Scripts
        {
            SourcePath = "\\OtherServer\Scripts"
            DestinationPath = $Node.DestinationPath
            Ensure = "Present"

        }

    }

}

July 18, 2014 at 7:13 am

thanks Jacob much appreciated, hopefully the example below shows what we are trying to do.

At the moment we are using just a standard foreach() statement and just enumerating through the windows features in our array $features .

Basically Is it possible to use the $Allnodes.Foreach() statement in a similar fashion but using the array stored in the hash table key Winfeatures within the configdata and do something like $ALLnodes.foreach($_.Winfeatures)

and use this to assign to the Name = $feature.

$configdata = @{

    AllNodes = @(
        @{  NodeName = "dscw2k8";
            Cluster = "SERVERX";
            Winfeatures =  @("NET-Framework-Core","NET-HTTP-Activation","Web-Static-Content","Web-Default-Doc",
	        "Web-Dir-Browsing","Web-Http-Errors","Web-Asp-Net","Web-Net-Ext","Web-ISAPI-Ext",
	        "Web-ISAPI-Filter","Web-Includes","Web-Http-Logging","Web-Log-Libraries","Web-Request-Monitor",
	        "Web-Http-Tracing","Web-Mgmt-Tools","Web-Scripting-Tools","Web-Mgmt-Service")
        }

    )

}


configuration netserverWindowsFeatures
{

$features = "NET-Framework-Core","NET-HTTP-Activation","Web-Static-Content","Web-Default-Doc",
	        "Web-Dir-Browsing","Web-Http-Errors","Web-Asp-Net","Web-Net-Ext","Web-ISAPI-Ext",
	        "Web-ISAPIFilter","Web-Includes","Web-Http-Logging","Web-Log-Libraries","Web-Request-Monitor",
	        "Web-Http-Tracing","Web-Mgmt-Tools","Web-Scripting-Tools","Web-Mgmt-Service"
    
    
    foreach($feature in $features)
    {
        Node $AllNodes.Where{$_.Cluster -eq "SERVERX"}.Nodename
        {
            WindowsFeature $feature
            {
                Name = $feature
                Ensure = "Present"
            }
            Log "netserverWindowsFeatures-$feature"
            {
                Message = "netserverWindowsFeatures Windows $feature updated"
                #DependsOn = "[WindowsFeature]"
            }

        }
    }

            
}
netserverWindowsFeatures -outputpath c:\mof\sample_NETAPPB -configuration $configdata 

July 18, 2014 at 9:33 am

I will have to test this out and get back to you. What happens when you run this? Do you get a .MOF file, an error message, or something else? I am just wanting to know what kind of behavior you are getting so I can compare it to what I get.

July 18, 2014 at 9:54 am

Alright, it's going to take someone with a much greater understanding of PowerShell than me to tell you how to do this. It is definitely supported, because if you just type Node $AllNodes. you get 2 options, Where and ForEach. However, digging into the syntax of ForEach on MSDN, I have no idea how you would use that in a DSC Configuration. Sorry I can't be of more assistance.

July 18, 2014 at 10:36 am

[blockquote]Basically Is it possible to use the $Allnodes.Foreach() statement in a similar fashion but using the array stored in the hash table key Winfeatures within the configdata and do something like $ALLnodes.foreach($_.Winfeatures) [/blockquote]

Technically, you can, but it's not necessary. I find the simple "foreach" loop more readable than the $collection.ForEach() method syntax anyway.

For your specific situation, it's helpful to know that DSC gives you access to an automatic $Node variable within the Node block. This $Node variable contains a reference to the hashtable associated with the node name, and you can get to the WinFeatures key of your hashtable from there. For example:

$configdata = @{
 
    AllNodes = @(
        @{  NodeName = "dscw2k8";
            Cluster = "SERVERX";
            Winfeatures =  @("NET-Framework-Core","NET-HTTP-Activation","Web-Static-Content","Web-Default-Doc",
	        "Web-Dir-Browsing","Web-Http-Errors","Web-Asp-Net","Web-Net-Ext","Web-ISAPI-Ext",
	        "Web-ISAPI-Filter","Web-Includes","Web-Http-Logging","Web-Log-Libraries","Web-Request-Monitor",
	        "Web-Http-Tracing","Web-Mgmt-Tools","Web-Scripting-Tools","Web-Mgmt-Service")
        }
 
    )
 
}
 
 
configuration netserverWindowsFeatures
{ 
    Node $AllNodes.Where{$_.Cluster -eq "SERVERX"}.NodeName
    {
        foreach($feature in $Node.Winfeatures)
        {
            WindowsFeature $feature
            {
                Name = $feature
                Ensure = "Present"
            }
        }
    } 
}

netserverWindowsFeatures -ConfigurationData $configdata

Now, if you really, really wanted to, you could have replaced that foreach loop with this syntax, but I don't really see the point:

configuration netserverWindowsFeatures
{ 
    Node $AllNodes.Where{$_.Cluster -eq "SERVERX"}.NodeName
    {
        $Node.Winfeatures.ForEach({
            WindowsFeature $_
            {
                Name = $_
                Ensure = "Present"
            } 
        })
    } 
}

Edit: I removed the Log resources from the configuration while I was writing and testing this, but you can put those back within the loops easily enough.

July 19, 2014 at 8:54 am

Jacob thanks for helping and thanks Dave for the examples , that's excellent , much appreciated ,

agreed the first example does looks easier to read and follow ,

and thanks for showing how you would use $collection.foreach() statement syntax, that has certainly enlightened me.

thanks Glenn

August 16, 2014 at 8:36 am

This works:

    Node $AllNodes.ForEach("Nodename")

Just tested it as I'm creating a new hydration kit .