DSC
DSC copied to clipboard
Unable to reuse `reference()` in set operation from get and test
Prerequisites
- [X] Write a descriptive title.
- [X] Make sure you are able to repro it on the latest version
- [X] Search the existing issues.
Steps to reproduce
When using the reference()
function, you need to use dot-path notation to access the data from the result for a resource operation. For both get
and test
operations, you can use the actualState
property of the return object to retrieve the state of the resource. However, for set
operations, you need to use either the beforeState
or afterState
property.
This means that you can't define a reference()
function once and reuse it across all operations - you need to define a separate configuration document.
You can reproduce this issue with this minimal configuration document:
# repro.dsc.config.yaml
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2023/08/config/document.json
resources:
- name: current user registry
type: Microsoft.Windows/Registry
properties:
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
_exist: true
- name: Echo Reference
type: Test/Echo
properties:
output: "[reference(resourceId('Microsoft.Windows/Registry', 'current user registry')).actualState.valueName]"
dependsOn:
- "[resourceId('Microsoft.Windows/Registry', 'current user registry')]"
Steps:
$config = Get-Content -Raw -Path ./repro.dsc.config.yaml
$config | dsc config get
$config | dsc config test
$config | dsc config set
Proposed fix
The following options occur to me:
- Do the step-in for
actualState
andafterState
on behalf of the users, instead of requiring them to manually step in with dot-notation - so instead ofreference(...).actualState.valueName
, the user would writereference(...).valueName
. Are there cases where users will want to get at values other than the canonical state of the resource with a reference? - Rename the
actualState
and/orafterState
properties to use the same name. I'm not sure I see a good option here, all of the new names I can think of are less descriptive of what's being returned. - Provide an error handler that specifically tries
afterState
for theset
operation if it can't find theactualState
key. This would quietly enable users to define one reference and reuse it across all operations, but it's a little bit non-obvious and adds a special code path.
Expected behavior
PS> $config | dsc config get
results:
- name: current user registry
type: Microsoft.Windows/Registry
result:
actualState:
$id: https://developer.microsoft.com/json-schemas/windows/registry/20230303/Microsoft.Windows.Registry.schema.json
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
valueData:
String: Windows 10 Enterprise
- name: Echo Reference
type: Test/Echo
result:
actualState:
output: ProductName
messages: []
hadErrors: false
PS> $config | dsc config test
results:
- name: current user registry
type: Microsoft.Windows/Registry
result:
desiredState:
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
_exist: true
actualState:
$id: https://developer.microsoft.com/json-schemas/windows/registry/20230303/Microsoft.Windows.Registry.schema.json
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
valueData:
String: Windows 10 Enterprise
_exist: true
_inDesiredState: true
inDesiredState: true
differingProperties: []
- name: Echo Reference
type: Test/Echo
result:
desiredState:
output: ProductName
actualState:
output: ProductName
inDesiredState: true
differingProperties: []
messages: []
hadErrors: false
PS> $config | dsc config set
results:
- name: current user registry
type: Microsoft.Windows/Registry
result:
beforeState:
$id: https://developer.microsoft.com/json-schemas/windows/registry/20230303/Microsoft.Windows.Registry.schema.json
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
valueData:
String: Windows 10 Enterprise
afterState:
$id: https://developer.microsoft.com/json-schemas/windows/registry/20230303/Microsoft.Windows.Registry.schema.json
keyPath: HKLM\Software\Microsoft\Windows NT\CurrentVersion
valueName: ProductName
changedProperties: []
- name: Echo Reference
type: Test/Echo
result:
beforeState:
output: ProductName
afterState:
output: ProductName
changedProperties: null
messages: []
hadErrors: false
Actual behavior
PS> $config | dsc config set
2024-04-09T15:36:27.710767Z ERROR dsc::subcommand: 95: Error: Parser: Member 'actualState' not found
Error details
2024-04-09T15:36:27.710767Z ERROR dsc::subcommand: 95: Error: Parser: Member 'actualState' not found
Environment data
Name Value
---- -----
PSVersion 7.4.1
PSEdition Core
GitCommitId 7.4.1
OS Microsoft Windows 10.0.22631
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Version
Latest build from main
Visuals
No response