-
Notifications
You must be signed in to change notification settings - Fork 52
Closed
Labels
Milestone
Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest version
- Search the existing issues.
Summary
Even thought that export is still expiremental, the following error is thrown when you execute export on a class-based DSC resource that doesn't have it implemented.
$document = @'
$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json
resources:
- name: Use class PowerShell resources
type: Microsoft.DSC/PowerShell
properties:
resources:
- name: PowerShell 7 Preview
type: Microsoft.WinGet.DSC/WinGetPackage
properties:
Id: Microsoft.PowerShell.Preview
Ensure: "Present"
'@
dsc config export -d $document
Skimming through the code, I think the issue lays in the fact when the Invoke
method is called which is empty:
# psDscAdapter.psm1
'Export' {
$t = $dscResourceInstance.GetType()
$method = $t.GetMethod('Export')
$resultArray = $method.Invoke($null, $null)
$addToActualState = $resultArray
}
Would it be good to include a new function and add it just before the operations are called in the switch statement:
function ValidateResourceOperationMethods {
[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[object] $resourceObject,
[Parameter(Mandatory = $false)]
[ValidateSet('Get', 'Set', 'Test', 'Export')]
[string] $operation = 'Get'
)
$operations = ($resourceObject | Get-Member | Where-Object {$_.MemberType -eq 'Method'}).Name
if (-not ($operations.Contains($operation))) {
$errmsg = 'Can not find method on "' + $resourceObject.GetType().Name + '". Please make sure the DSC resource implements "' + $operation + '".'
'ERROR: ' + $errmsg | Write-DscTrace
exit 1
}
}
function Invoke-DscOperation {
# truncated
switch ([dscResourceType]$cachedDscResourceInfo.ImplementationDetail) {
'ClassBased' {
try {
# load powershell class from external module
$resource = GetTypeInstanceFromModule -modulename $cachedDscResourceInfo.ModuleName -classname $cachedDscResourceInfo.Name
$dscResourceInstance = $resource::New()
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
}
}
# Add this line before executing the operation
ValidateResourceOperationMethods -resourceObject $dscResourceInstance -operation $Operation
switch ($Operation) {
'Get' {
$Result = $dscResourceInstance.Get()
$addToActualState.properties = $Result
}
'Set' {
$dscResourceInstance.Set()
}
'Test' {
$Result = $dscResourceInstance.Test()
$addToActualState.properties = [psobject]@{'InDesiredState' = $Result }
}
'Export' {
$t = $dscResourceInstance.GetType()
$method = $t.GetMethod('Export')
$resultArray = $method.Invoke($null, $null)
$addToActualState = $resultArray
}
}
}
catch {
'ERROR: ' + $_.Exception.Message | Write-DscTrace
exit 1
}
# truncated
}
Steps to reproduce
Run the code above if you have the Microsoft.WinGet.Dsc
module installed.
Expected behavior
User friendly message why the method cannot be called on the resource.
Actual behavior
2024-07-28T09:18:07.115768Z DEBUG : dsc_lib::dscresources::command_resource: 812: Process 'pwsh' id 14588 : PSDesiredStateConfiguration module version:
2024-07-28T09:18:07.116249Z DEBUG : dsc_lib::dscresources::command_resource: 812: Process 'pwsh' id 14588 : ERROR: You cannot call a method on a null-valued expression.
2024-07-28T09:18:07.116965Z ERROR dsc::subcommand: 166: Error: Command: Resource 'pwsh' [Exit code 1] manifest description: Error
Error details
No response
Environment data
Name Value
---- -----
PSVersion 7.4.3
PSEdition Core
GitCommitId 7.4.3
OS Microsoft Windows 10.0.19045
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Version
dsc 3.0.0-preview.8
Visuals
No response