DSC
DSC copied to clipboard
Multi-string support
Prerequisites
- [X] Write a descriptive title.
- [X] Make sure you are able to repro it on the latest version
- [X] Search the existing issues.
Summary
Problem statement
This morning, I was rambling on my keyboard and looking at some examples to migrate PSDSC configuration documents to DSC. Experimenting with the PSDesiredStateConfiguration/Script resource was like opening a Pandora's box, with odd behaviors emerging out of the shadows especially when using multi-strings.
That brought me to do some investigation and see where things are going wrong.
Investigation
The initial start of my investigation, was using the following document:
# powershell.script.dsc.config.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
resources:
- type: Microsoft.Windows/WindowsPowerShell
name: Run script
properties:
resources:
- name: Run script
type: PSDesiredStateConfiguration/Script
properties:
Ensure: "Present"
GetScript: |
$testFile = C:\Temp\test.txt
@{result = $(Get-Content $testFile)}
TestScript: |
Throw
SetScript: |
Throw
Running the script, gave me the following error message:
The strange thing while executing the document (dsc config get --path powershell.script.dsc.config.yaml
), is that a piece is cut off:
Now, forget about the fact on YAML. Let's dive into the JSON part and see why the error was thrown. What I would have expected, is the following JSON being passed through to Invoke-DscResource
:
// Example 1
{"GetScript":"$var = \"C:\\temp\\test.txt\"; @{result = $(Get-Content $var)}","SetScript":"throw","TestScript":"throw","type":"PSDesiredStateConfiguration/Script"}
Unfortunately, that does not happen, nor does the following JSONs are being passed through:
// Example 2
$res = @'
{"GetScript":["$var = \"C:\\temp\\test.txt\", "@{result = $(Get-Content $var)}"],"SetScript":"throw","TestScript":"throw","type":"PSDesiredStateConfiguration/Script"}
'@
// Example 3
$$string = @'
{
"GetScript": [
{
"$var": "C:\\Temp\\test.txt"
},
{
"@{result}": "Get-Content $var"
}
],
"SetScript": "throw",
"TestScript": "throw",
"type": "PSDesiredStateConfiguration/Script"
}
'@
That third one sticks out like a sore thumb to me too.
Thoughts and ideas
That brought me even deeper to look at the adapter code and a train of thoughts on how to potentially look at this.
Firstly, passing in example 2, which looks more naturally to me, only reveals the real error message when you change the following line and add the -ErrorAction Stop
parameter:
$invokeResult = Invoke-DscResource -Method $Operation -ModuleName $cachedDscResourceInfo.ModuleName -Name $cachedDscResourceInfo.Name -Property $property -ErrorAction Stop
The error message that is returned:
That still doesn't really say what is happening behind the scenes, so you've to dump out the objects.
Example 2 vs 1:
While example 1 is running smoothly, but example 2 is a breeze to type. It raises the question of why it doesn’t flow the same way when you input YAML through DSC's core engine.
Still, I was curious why the object was a mismatch and dove into the code. Looking at how the property hashtable is built, you can spot the difference and I applied the following:
# morph the INPUT object into a hashtable named "property" for the cmdlet Invoke-DscResource
$DesiredState.properties.psobject.properties | ForEach-Object -Begin { $property = @{} } -Process {
if ($_.Value.GetType().Name -eq 'Object[]')
{
$property[$_.Name] = $_.Value -as [System.String]
}
$property[$_.Name] = $_.Value
}
If you want me to raise a PR for the fix and create Pester tests around it, just let me know.
Steps to reproduce
See problem statement
Expected behavior
Apply multi-strings.
Actual behavior
Multi-strings are not passed through YAML.
Error details
No response
Environment data
Name Value
---- -----
PSVersion 5.1.22621.3880
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.22621.3880
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Version
dsc 3.0.0-preview.8
Visuals
No response