Skip to content

Passing object properties to Hashtable of class-based PowerShell resource #709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3 tasks done
JohnMcPMS opened this issue Mar 17, 2025 · 5 comments
Closed
3 tasks done
Labels
Issue-Bug Something isn't working Resolution-Fixed The issue is fixed
Milestone

Comments

@JohnMcPMS
Copy link
Collaborator

Prerequisites

  • Write a descriptive title.
  • Make sure you are able to repro it on the latest version
  • Search the existing issues.

Summary

When passing an object type property to a resource that is using the Microsoft.DSC/PowerShell adapter, the object is not converted to a Hashtable correctly.

This currently only affects the resource commands, as config complains about custom resources before attempting to execute them (Not implemented: Custom resource not supported). Not sure if that is a bug (resource should also block) or simply a TODO.

Steps to reproduce

  1. With this file:
# config.yaml

Action: Partial
Settings:
  experimentalFeatures:
    dsc3: true
  1. Install the Microsoft.WinGet.DSC module from PSGallery. This is the target resource class.
[DSCResource()]
class WinGetUserSettings
{
    # We need a key. Do not set.
    [DscProperty(Key)]
    [string]$SID

    # A hash table with the desired settings.
    [DscProperty(Mandatory)]
    [Hashtable]$Settings

    [DscProperty()]
    [WinGetAction]$Action = [WinGetAction]::Full
  1. Run the command:
> dsc.exe resource test -r Microsoft.WinGet.DSC/WinGetUserSettings -f config.yml

Expected behavior

Resource invocation successful

Actual behavior

2025-03-17T18:13:16.530836Z ERROR PID 8308: Exception: Exception setting "Settings": "Cannot convert value "@{experimentalFeatures=}" to type "System.Collections.Hashtable". Error: "Cannot convert the "@{experimentalFeatures=}" value of type "System.Management.Automation.PSCustomObject" to type "System.Collections.Hashtable".""

Error details

Environment data

Name                           Value
----                           -----
PSVersion                      7.5.0
PSEdition                      Core
GitCommitId                    7.5.0
OS                             Microsoft Windows 10.0.23828
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Version

3.0.0

Visuals

No response

@JohnMcPMS JohnMcPMS added Issue-Bug Something isn't working Need-Review labels Mar 17, 2025
@Gijsreyn
Copy link
Contributor

Hi @JohnMcPMS. I think you found something interesting. I was trying to reproduce the config part, and what you probably did in the first place, was something like this:

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: UserSettings
  type: Microsoft.WinGet.DSC/WinGetUserSettings
  properties:
    Action: 'Partial'
    Settings:
      experimentalFeatures:
        dsc3: true

This gives the error you reported, but it should have been:

$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Use class PowerShell resources
  type: Microsoft.DSC/PowerShell
  properties:
    resources:
    - name: PowerShell 7 Preview
      type: Microsoft.WinGet.DSC/WinGetUserSettings
      properties:
        Action: Partial
        Settings:
          experimentalFeatures:
            dsc3: true

This gives the same error message as the dsc resource command. Anyway, back to the interesting part. I was looking were the issue is going wrong, and it's on the lines responsible for converting the following in the psDscAdapter.psm1:

if ($DesiredState.properties) {
    # set each property of $dscResourceInstance to the value of the property in the $desiredState INPUT object
    $DesiredState.properties.psobject.properties | ForEach-Object -Process {
        $dscResourceInstance.$($_.Name) = $_.Value
    }
}

The $DesiredState is of class dscResourceObject, which sets the properties default to psobject. You opened something interesting, because the properties in this case aren't compared against the actual class constructed with $dscResourceInstance = $resource::New().
That's why you see the exception happening. To demonstrate the issue (and a workaround) a little bit more clearly, I simple added the following lines to convert the PSCustomObject to a hashtable:

if ($DesiredState.properties) {
  # set each property of $dscResourceInstance to the value of the property in the $desiredState INPUT object
  $DesiredState.properties.psobject.properties | ForEach-Object -Process {
      if ($_.Value.GetType().Name -eq 'PSCustomObject') {
          $hashTable = @{}
          $_.Value.psobject.properties | ForEach-Object { $hashTable[$_.Name] = $_.Value } 

          $dscResourceInstance.$($_.Name) = $hashTable
      }
      else 
      {
          Write-DscTrace -Message "Setting property: $($_.Name) to $($_.Value.TypeNameOfValue)"
          $dscResourceInstance.$($_.Name) = $_.Value    
      }
  }
}

Then the result ends in what you're looking for:

Image

It however asks the fundamental question I guess: how does dsc.exe parse the specific object types towards adapted resources?

@SteveL-MSFT or @michaeltlombardi , what are your thoughts on?

@JohnMcPMS
Copy link
Collaborator Author

It was my understanding that the config commands would be more efficient if you explicitly wrapped all of your adapted resources, but that it was not necessary. It seems strange to me that it would be required via config, but one cannot even supply --adapter to the resource usage commands.

@SteveL-MSFT
Copy link
Member

@JohnMcPMS the issue you are referring to is this #693 which I'm working on

@SteveL-MSFT
Copy link
Member

@Gijsreyn I think you are on the right track for a fix, can you create a PR with added test?

@SteveL-MSFT
Copy link
Member

This should be fixed by #713

@SteveL-MSFT SteveL-MSFT added Resolution-Fixed The issue is fixed and removed Need-Review labels Mar 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Bug Something isn't working Resolution-Fixed The issue is fixed
Projects
None yet
Development

No branches or pull requests

3 participants