Wednesday, April 29, 2015

Using a Hashtable in a PowerShell DSC Custom Resource

When creating a new DSC resource property using the DSC resource designer you are allowed to specify the type as ‘Hashtable’.  Though I’ve created a lot of resources I haven’t used a property of this type yet, but today somebody asked me about it.

My first attempt to figure it out was to look at existing resources but I wasn’t able to find any.

My next attempt was to create a sample DSC resource to try it out.  The bad news is that it doesn’t work, at least the generated DSC resource code doesn’t work.  The good news is that it isn’t difficult to make it work.

Check out the snippets!

 

### Create a simple resource with a Hashtable property

New-xDscResource -Name cBar -Path 'C:\Program Files\WindowsPowerShell\Modules\cBar' -Property @(

    New-xDscResourceProperty -Name DisplayName -Type String    -Attribute Key

    New-xDscResourceProperty -Name Hashtable   -Type Hashtable -Attribute Write

)

 

### Edit the generated files

psedit 'C:\Program Files\WindowsPowerShell\Modules\cBar\DSCResources\cBar\cBar.psm1'

psedit 'C:\Program Files\WindowsPowerShell\Modules\cBar\DSCResources\cBar\cBar.schema.mof'

 

### Create an empty PSM1 file for the new module

Set-Content -Value "### Test File" -Path 'C:\Program Files\WindowsPowerShell\Modules\cBar\cBar.psm1' -Encoding UTF8

 

### Create a configuration with our new resource

Configuration SampleHashtable

{

    Import-DscResource -Module cBar

 

    Node (hostname)

    {

        cBar Sample

        {

            DisplayName   = 'NTDEV AD'

            Hashtable     = @{this='that'}

        }

    }

}

 

### Generate the MOF

SampleHashtable -OutputPath "$env:TEMP\SampleHashtable"

 

### Review the MOF

psedit "$env:TEMP\SampleHT\$(hostname).mof"

 

### Enact the config

Start-DscConfiguration -Path "$env:TEMP\SampleHashtable" -Verbose -Force -Wait

 

### Replace the DSC resource module code

Set-Content -Path 'C:\Program Files\WindowsPowerShell\Modules\cBar\DSCResources\cBar\cBar.psm1' -Value @'

function Get-TargetResource

{

      [CmdletBinding()]

      [OutputType([System.Collections.Hashtable])]

      param

      (

             [parameter(Mandatory = $true)]

             [System.String]

             $DisplayName

      )

}

 

function Set-TargetResource

{

      [CmdletBinding()]

      param

      (

             [parameter(Mandatory = $true)]

             [System.String]

             $DisplayName,

 

             [CimInstance]

             $Hashtable

      )

}

 

function Test-TargetResource

{

      [CmdletBinding()]

      [OutputType([System.Boolean])]

      param

      (

             [parameter(Mandatory = $true)]

             [System.String]

             $DisplayName,

 

             [CimInstance]

             $Hashtable

      )

    Write-Verbose "HT Properties: $($HT.CimInstanceProperties -join ',')"

    Write-Verbose "HT key:        $($HT.Key)"

    Write-Verbose "HT value:      $($HT.Value)"

    Write-Output $true

}

 

Export-ModuleMember -Function *-TargetResource

'@

 

<#

### My VM is on WMF 4 so I still need the heavy handed

### approach to getting the LCM to reload my DSC resource.

### find the Process that is hosting the DSC engine

$dscProcessID = Get-WmiObject msft_providers |

Where-Object {$_.provider -like 'dsccore'} |

Select-Object -ExpandProperty HostProcessIdentifier

### Kill it

Get-Process -Id $dscProcessID | Stop-Process -Force

#>

 

Here’s the LCM verbose output:

VERBOSE: Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigu

rationManager,'namespaceName' = root/Microsoft/Windows/DesiredStateConfiguration'.

VERBOSE: An LCM method call arrived from computer IAMVM55763 with user sid S-1-5-21-32967844-2432541121-1187827502-500.

VERBOSE: [IAMVM55763]: LCM:  [ Start  Set      ]

VERBOSE: [IAMVM55763]: LCM:  [ Start  Resource ]  [[cBar]Sample]

VERBOSE: [IAMVM55763]: LCM:  [ Start  Test     ]  [[cBar]Sample]

VERBOSE: [IAMVM55763]:                            [[cBar]Sample] HT Properties:

VERBOSE: [IAMVM55763]:                            [[cBar]Sample] HT key:

VERBOSE: [IAMVM55763]:                            [[cBar]Sample] HT value:

VERBOSE: [IAMVM55763]: LCM:  [ End    Test     ]  [[cBar]Sample]  in 0.3590 seconds.

VERBOSE: [IAMVM55763]: LCM:  [ Skip   Set      ]  [[cBar]Sample]

VERBOSE: [IAMVM55763]: LCM:  [ End    Resource ]  [[cBar]Sample]

VERBOSE: [IAMVM55763]: LCM:  [ End    Set      ]    in  0.9177 seconds.

VERBOSE: Operation 'Invoke CimMethod' complete.

VERBOSE: Time taken for configuration job to complete is 1.256 seconds

 

No comments: