Hello, I would like to know why the Configuration Data file(.psd1) for the DSC is written in PSON (Powershell) and not in JSON which is more common.
If I would like to create such a file through a script I need to use some unsupported Functions like ConvertTo/FROM-PSON which I have found on the Internet, instead I could use the already supported ConvertTO/FROM- JSON.
Well at least they could give the ConvertTo/From-PSON out of the box as they give the JSON onces.
The .psd1 file is a PowerShell Module Manifest file. Modules are the recommended way PowerShell functionality is delivered.
Why would a PowerShell file be written in JSON?
DSC is a PowerShell extension - its not really reasonable to expect it to be written in anything but PowerShell
DSC only requires you to pass in a Hashtable object for the -ConfigurationData parameter when you call the config. It doesn’t care how you store that hashtable on disk; there’s no reason you can’t use JSON.
There’s one slight snag, which is that ConvertFrom-Json will give you PSCustomObjects instead of Hashtables, so you need a bit of code to make that conversion before passing your configuration data to a DSC config:
$ht = @{
AllNodes = @(
@{
NodeName = 'Node1'
Whatever = 'Something'
}
)
NonNodeData = @{
SomeOtherThing = 'Whatever'
SomeArray = @()
}
}
# Simulating saving the JSON to disk and then reloading it
$object = $ht | ConvertTo-Json | ConvertFrom-Json
# Now $object is a pscustomobject, as are any nested hashtables inside its structure
function ConvertPSObjectToHashtable
{
param (
[Parameter(ValueFromPipeline)]
$InputObject
)
process
{
if ($null -eq $InputObject) { return $null }
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string])
{
$collection = @(
foreach ($object in $InputObject) { ConvertPSObjectToHashtable $object }
)
Write-Output -NoEnumerate $collection
}
elseif ($InputObject -is [psobject])
{
$hash = @{}
foreach ($property in $InputObject.PSObject.Properties)
{
$hash[$property.Name] = ConvertPSObjectToHashtable $property.Value
}
$hash
}
else
{
$InputObject
}
}
}
$converted = ConvertPSObjectToHashtable $object
# $converted is now equivalent to the original $ht, and can be passed into your configuration.
SomeDSCConfiguration -ConfigurationData $converted
Thanks a lot, great answer like always!
^bump^
As the response above illustrates, JSON is just tons easier to work with than nested hash-tables - for filtering, saving to files/db, getting from a web-service, etc.
Sure would help with some of my tfs deployment scripts.