Thursday, July 10, 2014

Implementing a Custom PowerShell DSC Resource

Lately I’ve been working on custom Desired State Configuration resources, and learning as I go.

The basic pattern I’m following is below.  Basically I do the following:

  • Search for the target object
  • If found, compare the target object properties to the properties that I get from DSC

On thing I’ve latched onto is the $PSBoundParameters automatic variable.  It has been a handy way to loop through the properties that are considered ‘Desired’.  In my experimenting I’ve discovered that I also need to loop through the properties of the target object to identify properties that are not ‘Desired’ (this little discovery wasn’t a happy one since I have more work to do).

Anyhow, here is a snippet for the Test-TargetResource function:

Function Get-TargetResource

{

    # TODO: Add parameters here

    # Make sure to use the same parameters for

    # Get-TargetResource, Set-TargetResource, and Test-TargetResource

    param(

    )

}

 

Function Set-TargetResource

{

    # TODO: Add parameters here

    # Make sure to use the same parameters for

    # Get-TargetResource, Set-TargetResource, and Test-TargetResource

    param(

    )

}

 

Function Test-TargetResource

{

    # TODO: Add parameters here

    # Make sure to use the same parameters for

    # Get-TargetResource, Set-TargetResource, and Test-TargetResource

    param(

      [parameter(Mandatory = $true)]

             [System.String]

             $DisplayName,

 

             [System.String]

             $Description,

 

             [Switch]

             $Enabled,

 

             [System.String]

             $StringProperty1,

 

             [System.String]

             $StringProperty2,

 

             [System.String]

             $StringProperty3,

 

             [System.String]

            $StringPropertyWithSpecialComparison,

 

             [ValidateSet("Present","Absent")]

             [System.String]

             $Ensure

    )

 

    $PSBoundParameters

 

    $targetObject = Get-SomeTargetObject

 

    if ($Ensure -eq 'Present')

    {

        if ($targetObject -eq $null)

        {

            Write-Verbose "Target Object '$DisplayName' not found."

            return $false

        }

        elseif ($targetObject -is [array])

        {

            Write-Verbose "Mulitple Target Objects found.  This will be corrected by deleting the objects then creating a new one based on the desirable state."

            return $false

        }

        else

        {

            Write-Verbose "Target Object found, diffing the properties: $($targetObject.ObjectID)"

            $objectsAreTheSame = $true

            foreach ($boundParameter in $PSBoundParameters.GetEnumerator())

            {

                Write-Verbose "Comparing $($boundParameter.Key)"

                switch ($boundParameter.Key)

                {

                    {$_ -in @(

                        'StringProperty1'

                        'StringProperty2' 

                        'StringProperty3'              

                    )} {

                        Write-Verbose " From DSC: $($boundParameter.Key)"

                        Write-Verbose " From Obj: $($targetObject.($boundParameter.Key))"

                        if ($boundParameter.Value -ne $targetObject.($boundParameter.Key))

                        {

                            Write-Verbose " Target Object property is not the same."

                            $objectsAreTheSame = $false

                        }

                    }

                    'StringPropertyWithSpecialComparison' {

                        Write-Verbose " From DSC: $($boundParameter.Key)"

                        Write-Verbose " From Obj: $($targetObject.SpecialPropertyNameThatDoesNotMatchTheBoundParameter)"

                        if ($boundParameter.Value -ne $targetObject.SpecialPropertyNameThatDoesNotMatchTheBoundParameter)

                        {

                            Write-Verbose " Target Object property is not the same."

                            $objectsAreTheSame = $false

                        }

                    }

                }#Closing: switch

            }#Closing: foreach 

        }#Closing: else

    }#Closing: if ($Ensure -eq 'Present')                 

}#Closing: Function Test-TargetResource

 

No comments: