Skip to content
Merged
24 changes: 24 additions & 0 deletions powershell-adapter/Tests/win_powershellgroup.tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,22 @@ class PSClassResource {
[void] Set() {

}

static [PSClassResource[]] Export()
{
$resultList = [System.Collections.Generic.List[PSClassResource]]::new()
$resultCount = 5
if ($env:PSClassResourceResultCount) {
$resultCount = $env:PSClassResourceResultCount
}
1..$resultCount | %{
$obj = New-Object PSClassResource
$obj.Name = "Object$_"
$resultList.Add($obj)
}

return $resultList.ToArray()
}
}
'@

Expand Down Expand Up @@ -350,4 +366,12 @@ class PSClassResource {
$LASTEXITCODE | Should -Be 0
$out.afterstate.InDesiredState | Should -Be $true
}

It 'Export works with class-based PS DSC resources' -Skip:(!$IsWindows) {

$out = dsc resource export -r PSClassResource/PSClassResource | ConvertFrom-Json
$LASTEXITCODE | Should -Be 0
$out | Should -Not -BeNullOrEmpty
$out.resources.count | Should -Be 5
}
}
45 changes: 42 additions & 3 deletions powershell-adapter/psDscAdapter/win_psDscAdapter.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,21 @@ function Invoke-DscOperation {
$addToActualState.properties = [psobject]@{'InDesiredState' = $Result }
}
'Export' {
$t = $dscResourceInstance.GetType()
$method = $t.GetMethod('Export')
$resultArray = $method.Invoke($null, $null)
$method = ValidateMethod -operation $Operation -class $dscResourceInstance
$resultArray = @()
$raw_obj_array = $method.Invoke($null, $null)
foreach ($raw_obj in $raw_obj_array) {
$Result_obj = @{}
$ValidProperties | ForEach-Object {
if ($raw_obj.$_ -is [System.Enum]) {
$Result_obj[$_] = $raw_obj.$_.ToString()
}
else {
$Result_obj[$_] = $raw_obj.$_
}
}
$resultArray += $Result_obj
}
$addToActualState = $resultArray
}
}
Expand Down Expand Up @@ -532,6 +544,33 @@ function GetTypeInstanceFromModule {
return $instance
}

# ValidateMethod checks if the specified method exists in the class
function ValidateMethod {
param (
[Parameter(Mandatory = $true)]
[ValidateSet('Export', 'WhatIf')]
[string] $operation,
[Parameter(Mandatory = $true)]
[object] $class
)

$t = $class.GetType()
$methods = $t.GetMethods() | Where-Object -Property Name -EQ $operation
$method = foreach ($mt in $methods) {
if ($mt.GetParameters().Count -eq 0) {
$mt
break
}
}

if ($null -eq $method) {
"Method '$operation' not implemented by resource '$($t.Name)'" | Write-DscTrace -Operation Error
exit 1
}

return $method
}

# cached resource
class dscResourceCacheEntry {
[string] $Type
Expand Down
158 changes: 86 additions & 72 deletions powershell-adapter/windowspowershell.dsc.resource.json
Original file line number Diff line number Diff line change
@@ -1,41 +1,14 @@
{
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
"type": "Microsoft.Windows/WindowsPowerShell",
"version": "0.1.0",
"kind": "adapter",
"description": "Resource adapter to classic DSC Powershell resources in Windows PowerShell.",
"tags": [
"PowerShell"
],
"adapter": {
"list": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"./psDscAdapter/powershell.resource.ps1 List"
]
},
"config": "full"
},
"get": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Get"
],
"input": "stdin"
},
"set": {
"$schema": "https://aka.ms/dsc/schemas/v3/bundled/resource/manifest.json",
"type": "Microsoft.Windows/WindowsPowerShell",
"version": "0.1.0",
"kind": "adapter",
"description": "Resource adapter to classic DSC Powershell resources in Windows PowerShell.",
"tags": [
"PowerShell"
],
"adapter": {
"list": {
"executable": "powershell",
"args": [
"-NoLogo",
Expand All @@ -44,39 +17,80 @@
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Set"
],
"input": "stdin",
"preTest": true
},
"test": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Test"
],
"input": "stdin",
"return": "state"
},
"validate": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Validate"
]
},
"exitCodes": {
"0": "Success",
"1": "Error"
}
"./psDscAdapter/powershell.resource.ps1 List"
]
},
"config": "full"
},
"get": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Get"
],
"input": "stdin"
},
"set": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Set"
],
"input": "stdin",
"preTest": true
},
"test": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Test"
],
"input": "stdin",
"return": "state"
},
"export": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Export"
],
"input": "stdin",
"return": "state"
},
"validate": {
"executable": "powershell",
"args": [
"-NoLogo",
"-NonInteractive",
"-NoProfile",
"-ExecutionPolicy",
"Bypass",
"-Command",
"$Input | ./psDscAdapter/powershell.resource.ps1 Validate"
]
},
"exitCodes": {
"0": "Success",
"1": "Error"
}
}
Loading