Here’s a quick function to allow you something close to splatting with DSC resources:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-DscSplattedResource { | |
[CmdletBinding()] | |
Param( | |
[String] | |
$ResourceName, | |
[String] | |
$ExecutionName, | |
[hashtable] | |
$Properties | |
) | |
$stringBuilder = [System.Text.StringBuilder]::new() | |
$null = $stringBuilder.AppendLine("Param([hashtable]`$Parameters)") | |
$null = $stringBuilder.AppendLine(" $ResourceName $ExecutionName { ") | |
foreach($PropertyName in $Properties.keys) { | |
$null = $stringBuilder.AppendLine("$PropertyName = `$(`$Parameters['$PropertyName'])") | |
} | |
$null = $stringBuilder.AppendLine("}") | |
Write-Debug ("Generated Resource Block = {0}" -f $stringBuilder.ToString()) | |
[scriptblock]::Create($stringBuilder.ToString()).Invoke($Properties) | |
} | |
Set-Alias –Name x –Value Get-DscSplattedResource |
Here’s why you may need it.
In DSC, quite often you need to specify a resource with some values like so:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Configuration MyDscConfig { | |
$Allnodes.nodename { | |
ChocolateyPackage Putty { | |
Ensure = 'Present' | |
Name = 'Putty' | |
Version = 'Latest' | |
ChocolateyOptions = @{ source = 'https://chocolatey.org/api/v2/' } | |
} | |
} | |
} |
But what if you have an hashtable readily available:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Assuming you already have this hashtable | |
$MyHash = @{ | |
Ensure = 'Present' | |
Name = 'Putty' | |
Version = 'Latest' | |
ChocolateyOptions = @{ source = 'https://chocolatey.org/api/v2/' } | |
} | |
Configuration MyDscConfig { | |
$Allnodes.nodename { | |
ChocolateyPackage Putty { | |
Ensure = $MyHash['Ensure'] | |
Name = $MyHash['Name'] | |
Version = $MyHash['Version'] | |
ChocolateyOptions = $MyHash['ChocolateyOptions'] | |
} | |
} | |
} |
Or if you’re iterating through a list of hashtable, and some don’t contain a value:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Assuming you already have this hashtable | |
$MyHashes = @( | |
@{ | |
Ensure = 'Present' | |
Name = 'Putty' | |
Version = 'Latest' | |
ChocolateyOptions = @{ source = 'https://chocolatey.org/api/v2/' } | |
}, | |
@{ | |
Ensure = 'Absent' | |
Name = 'notepadplusplus' | |
} | |
) | |
Configuration MyDscConfig { | |
$Allnodes.nodename { | |
#The second Item will error because of missing properties | |
foreach($MyHash in $MyHashes) { | |
ChocolateyPackage Putty { | |
Ensure = $MyHash['Ensure'] | |
Name = $MyHash['Name'] | |
Version = $MyHash['Version'] | |
ChocolateyOptions = $MyHash['ChocolateyOptions'] | |
} | |
} | |
} | |
} |
Well, until splatting is supported natively in DSC, you could use the following function as a way to support splatting in your configurations:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-DscSplattedResource { | |
[CmdletBinding()] | |
Param( | |
[String] | |
$ResourceName, | |
[String] | |
$ExecutionName, | |
[hashtable] | |
$Properties | |
) | |
$stringBuilder = [System.Text.StringBuilder]::new() | |
$null = $stringBuilder.AppendLine("Param([hashtable]`$Parameters)") | |
$null = $stringBuilder.AppendLine(" $ResourceName $ExecutionName { ") | |
foreach($PropertyName in $Properties.keys) { | |
$null = $stringBuilder.AppendLine("$PropertyName = `$(`$Parameters['$PropertyName'])") | |
} | |
$null = $stringBuilder.AppendLine("}") | |
Write-Debug ("Generated Resource Block = {0}" -f $stringBuilder.ToString()) | |
[scriptblock]::Create($stringBuilder.ToString()).Invoke($Properties) | |
} | |
Set-Alias –Name x –Value Get-DscSplattedResource |
Be careful in which scope you’re executing this function, because DSC expect the scriptblock invoke in its own scope, not from another module.
But using this trick you can now do something like:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Assuming you already have this hashtable | |
$MyHashes = @( | |
@{ | |
Ensure = 'Present' | |
Name = 'Putty' | |
Version = 'Latest' | |
ChocolateyOptions = @{ source = 'https://chocolatey.org/api/v2/' } | |
}, | |
@{ | |
Ensure = 'Absent' | |
Name = 'notepadplusplus' | |
} | |
) | |
. .\Get-DscSplattedResource.ps1 | |
Configuration MyDscConfig { | |
$Allnodes.nodename { | |
#The second Item will now work | |
foreach($MyHash in $MyHashes) { | |
# 'x' is an alias for my Get-DscSplattedResource function | |
x ChocolateyPackage $MyHash['name'] $MyHash | |
} | |
} | |
} |
Thank you for this awesome trick!
LikeLike
Thank you for this valuable idea! I tried it on a 1300 line DSC config and reduced it to under 200 lines. Much more readable with less duplication. One minor thing I noticed, after the config completed, was that the DependsOn values retrieved from Get-DscConfigurationStatus showed duplicate entries (i.e. the DependsOn value showed up twice). This didn’t affect the outcome as far as I can tell, and it may be my implementation of your suggestion that may have caused it so just wondering if you’ve observed it too. Thanks again well done.
LikeLike