Skip to content

Commit 7b7f7fd

Browse files
committed
Add credential support on PowerShell adapters
1 parent a42e0d9 commit 7b7f7fd

File tree

5 files changed

+81
-11
lines changed

5 files changed

+81
-11
lines changed

powershell-adapter/Tests/TestClassResource/0.0.1/TestClassResource.psm1

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class TestClassResource : BaseTestClass
2929
[DscProperty()]
3030
[string] $EnumProp
3131

32+
[DscProperty()]
33+
[PSCredential] $Credential
34+
3235
[string] $NonDscProperty # This property shouldn't be in results data
3336

3437
hidden

powershell-adapter/Tests/powershellgroup.config.tests.ps1

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,22 @@ Describe 'PowerShell adapter resource tests' {
237237
}
238238
}
239239
}
240+
241+
It 'Config works with credential object' {
242+
$yaml = @"
243+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
244+
resources:
245+
- name: Class-resource Info
246+
type: TestClassResource/TestClassResource
247+
properties:
248+
Name: 'TestClassResource'
249+
Credential:
250+
UserName: 'User'
251+
Password: 'Password'
252+
"@
253+
$out = dsc config get -i $yaml | ConvertFrom-Json
254+
$LASTEXITCODE | Should -Be 0
255+
$out.results[0].result.actualState.result[0].properties.Credential.UserName | Should -Be 'User'
256+
$out.results[0].result.actualState.result[0].properties.Credential.Password | Should -BeNullOrEmpty
257+
}
240258
}

powershell-adapter/Tests/win_powershellgroup.tests.ps1

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,4 +211,25 @@ resources:
211211
$LASTEXITCODE | Should -Be 0
212212
$out.results[0].result.inDesiredState | Should -Be $inDesiredState
213213
}
214+
215+
It 'Should be able to test against a service with credentials' -Skip:(!$IsWindows) {
216+
$yaml = @"
217+
`$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
218+
resources:
219+
- name: Test service
220+
type: Microsoft.Windows/WindowsPowerShell
221+
properties:
222+
resources:
223+
- name: Test service
224+
type: PSDesiredStateConfiguration/Service
225+
properties:
226+
Name: 'W32Time'
227+
Credential:
228+
Username: "User"
229+
Password: "Password"
230+
"@
231+
$out = dsc config test -i $yaml | ConvertFrom-Json
232+
$LASTEXITCODE | Should -Be 0
233+
$out.results[0].result.inDesiredState | Should -Be $false
234+
}
214235
}

powershell-adapter/psDscAdapter/psDscAdapter.psm1

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -421,13 +421,11 @@ function Invoke-DscOperation {
421421
$DesiredState.properties.psobject.properties | ForEach-Object -Process {
422422
# handle input objects by converting them to a hash table
423423
if ($_.Value -is [System.Management.Automation.PSCustomObject]) {
424-
Write-DscTrace -Message "The object is a PSCustomObject"
425-
$_.Value.psobject.properties | ForEach-Object -Begin {
426-
$propertyHash = @{}
427-
} -Process {
428-
$propertyHash[$_.Name] = $_.Value
429-
} -End {
430-
$dscResourceInstance.$($_.Name) = $propertyHash
424+
if ($_.Name -like '*Credential*' -and $_.Value.Username -and $_.Value.Password) {
425+
$dscResourceInstance.$($_.Name) = [System.Management.Automation.PSCredential]::new($_.Value.Username, (ConvertTo-SecureString -AsPlainText $_.Value.Password -Force))
426+
}
427+
else {
428+
$dscResourceInstance.$($_.Name) = $_.Value.psobject.properties | ForEach-Object -Begin { $propertyHash = @{} } -Process { $propertyHash[$_.Name] = $_.Value } -End { $propertyHash }
431429
}
432430
}
433431
else {

powershell-adapter/psDscAdapter/win_psDscAdapter.psm1

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,12 @@ function Invoke-DscOperation {
364364
# morph the INPUT object into a hashtable named "property" for the cmdlet Invoke-DscResource
365365
$DesiredState.properties.psobject.properties | ForEach-Object -Begin { $property = @{} } -Process {
366366
if ($_.Value -is [System.Management.Automation.PSCustomObject]) {
367-
$property[$_.Name] = $_.Value.psobject.properties | ForEach-Object -Begin { $propertyHash = @{} } -Process { $propertyHash[$_.Name] = $_.Value } -End { $propertyHash }
367+
if ($_.Name -like '*Credential*' -and $_.Value.Username -and $_.Value.Password) {
368+
$property[$_.Name] = [System.Management.Automation.PSCredential]::new($_.Value.Username, (ConvertTo-SecureString -AsPlainText $_.Value.Password -Force))
369+
}
370+
else {
371+
$property[$_.Name] = $_.Value.psobject.properties | ForEach-Object -Begin { $propertyHash = @{} } -Process { $propertyHash[$_.Name] = $_.Value } -End { $propertyHash }
372+
}
368373
}
369374
else {
370375
$property[$_.Name] = $_.Value
@@ -373,7 +378,7 @@ function Invoke-DscOperation {
373378

374379
# using the cmdlet the appropriate dsc module, and handle errors
375380
try {
376-
Write-DscTrace -Operation Debug -Message "Module: $($cachedDscResourceInfo.ModuleName), Name: $($cachedDscResourceInfo.Name), Property: $($property)"
381+
Write-DscTrace -Operation Debug -Message "Module: $($cachedDscResourceInfo.ModuleName), Name: $($cachedDscResourceInfo.Name), Property: $($property | ConvertTo-Json -Compress)"
377382
$invokeResult = Invoke-DscResource -Method $Operation -ModuleName $cachedDscResourceInfo.ModuleName -Name $cachedDscResourceInfo.Name -Property $property -ErrorAction Stop
378383

379384
if ($invokeResult.GetType().Name -eq 'Hashtable') {
@@ -402,7 +407,18 @@ function Invoke-DscOperation {
402407
if ($DesiredState.properties) {
403408
# set each property of $dscResourceInstance to the value of the property in the $desiredState INPUT object
404409
$DesiredState.properties.psobject.properties | ForEach-Object -Process {
405-
$dscResourceInstance.$($_.Name) = $_.Value
410+
# handle input objects by converting them to a hash table
411+
if ($_.Value -is [System.Management.Automation.PSCustomObject]) {
412+
if ($_.Name -like '*Credential*' -and $_.Value.Username -and $_.Value.Password) {
413+
$dscResourceInstance.$($_.Name) = [System.Management.Automation.PSCredential]::new($_.Value.Username, (ConvertTo-SecureString -AsPlainText $_.Value.Password -Force))
414+
}
415+
else {
416+
$dscResourceInstance.$($_.Name) = $_.Value.psobject.properties | ForEach-Object -Begin { $propertyHash = @{} } -Process { $propertyHash[$_.Name] = $_.Value } -End { $propertyHash }
417+
}
418+
}
419+
else {
420+
$dscResourceInstance.$($_.Name) = $_.Value
421+
}
406422
}
407423
}
408424

@@ -444,9 +460,23 @@ function Invoke-DscOperation {
444460
}
445461

446462
# morph the INPUT object into a hashtable named "property" for the cmdlet Invoke-DscResource
447-
$DesiredState.properties.psobject.properties | ForEach-Object -Begin { $property = @{} } -Process { $property[$_.Name] = $_.Value }
463+
$DesiredState.properties.psobject.properties | ForEach-Object -Begin { $property = @{} } -Process {
464+
if ($_.Value -is [System.Management.Automation.PSCustomObject]) {
465+
if ($_.Name -Like '*Credential*' -and $_.Value.Username -and $_.Value.Password) {
466+
$property[$_.Name] = [System.Management.Automation.PSCredential]::new($_.Value.Username, (ConvertTo-SecureString -AsPlainText $_.Value.Password -Force))
467+
}
468+
else {
469+
$property[$_.Name] = $_.Value.psobject.properties | ForEach-Object -Begin { $propertyHash = @{} } -Process { $propertyHash[$_.Name] = $_.Value } -End { $propertyHash }
470+
}
471+
}
472+
else {
473+
$property[$_.Name] = $_.Value
474+
}
475+
}
476+
448477
# using the cmdlet from PSDesiredStateConfiguration module in Windows
449478
try {
479+
Write-DscTrace -Operation Debug -Message "Module: $($cachedDscResourceInfo.ModuleName), Name: $($cachedDscResourceInfo.Name), Property: $($property | ConvertTo-Json -Compress)"
450480
$invokeResult = Invoke-DscResource -Method $Operation -ModuleName $cachedDscResourceInfo.ModuleName -Name $cachedDscResourceInfo.Name -Property $property
451481
if ($invokeResult.GetType().Name -eq 'Hashtable') {
452482
$invokeResult.keys | ForEach-Object -Begin { $ResultProperties = @{} } -Process { $ResultProperties[$_] = $invokeResult.$_ }

0 commit comments

Comments
 (0)