Skip to content

Instantly share code, notes, and snippets.

@mgreenegit
Created May 3, 2022 16:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgreenegit/e3a9b4e136fc2d510cf87e20390daa44 to your computer and use it in GitHub Desktop.
Save mgreenegit/e3a9b4e136fc2d510cf87e20390daa44 to your computer and use it in GitHub Desktop.
Simple example of class resource for Windows service
# This is the Get function
function Get-Resource {
param(
[string]$status,
[string]$starttype
)
$service = Get-Service winmgmt
# Information returned by Get will be available in Azure via API
return @{
status = $service.status
starttype = $service.starttype
}
}
# This is the Set function
function Set-Resource {
param(
[string]$status,
[string]$starttype
)
Start-Service winmgmt
Set-Service winmgmt -startuptype 'Automatic'
}
# This is the Test function
function Test-Resource {
param(
[string]$status,
[string]$starttype
)
$test = $false
$service = Get-Service winmgmt
$test = 'Running' -eq $service.status -and `
'Automatic' -eq $service.starttype
return $test
}
# This provides a simple way to show more information in phrase
function Get-AdditionalText {
return '#psdsc'
}
class DscProperties {
[DscProperty(Key)]
[string] $status
[DscProperty()]
[string] $starttype
}
########## No need to edit below this line ##########
class Reason {
[DscProperty()]
[string] $Code
[DscProperty()]
[string] $Phrase
}
[DscResource()]
class ConfigurationResource : DscProperties {
[DscProperty(NotConfigurable)]
[Reason[]]$Reasons
[ConfigurationResource] Get() {
# Splat properties to Get function
$DscProperties = $this.GetConfigurableDscProperties()
$get = Get-Resource @DscProperties
# Adds Reasons to get
$additionalText = Get-AdditionalText
$get.Add('Reasons', $this.FormatReasons($get, $additionalText))
# Return hashtable produced by Get function
return $get
}
[Void] Set() {
# Splat properties to Set function
$DscProperties = $this.GetConfigurableDscProperties()
Set-Resource @DscProperties
}
[Bool] Test() {
# Splat properties to Test function
$DscProperties = $this.GetConfigurableDscProperties()
return Test-Resource @DscProperties
}
[Hashtable] GetConfigurableDscProperties() {
# This method returns a hashtable of properties with two special workarounds
# The hashtable will not include any properties marked as "NotConfigurable"
# Any properties with a ValidateSet of "True","False" will beconverted to Boolean type
# The intent is to simplify splatting to functions
$DscProperties = @{}
foreach ($property in [DscProperties].GetProperties().Name) {
# Checks if "NotConfigurable" attribute is set
$notConfigurable = [DscProperties].GetProperty($property).GetCustomAttributes($false).Where({ $_ -is [System.Management.Automation.DscPropertyAttribute] }).NotConfigurable
if (!$notConfigurable) {
$value = $this.$property
# Gets the list of valid values from the ValidateSet attribute
$validateSet = [DscProperties].GetProperty($property).GetCustomAttributes($false).Where({ $_ -is [System.Management.Automation.ValidateSetAttribute] }).ValidValues
if ($validateSet) {
# Workaround for boolean types
if ($null -eq (Compare-Object @('True', 'False') $validateSet)) {
$value = [System.Convert]::ToBoolean($this.$property)
}
}
# Add property to new
$DscProperties.add($property, $value)
}
}
return $DscProperties
}
[Reason[]] FormatReasons([hashtable]$get, [string]$additionalText) {
# This method takes information about a DSC resource and returns an array of Reason objects
# Including text for phrase that will render well in a browser
$DscProperties = $this.GetConfigurableDscProperties()
$state0 = $state1 = $null
foreach ($key in $DscProperties.Keys) {
if ($DscProperties.$key -eq $get.$key) {
$state0 += "`t`t[+] $key" + ':' + "`n`t`t`tExpected value to be `"$($DscProperties.$key)`"`n`t`t`tActual value was `"$($get.$key)`"`n"
}
else {
$state1 += "`t`t[-] $key" + ':' + "`n`t`t`tExpected value to be `"$($DscProperties.$key)`"`n`t`t`tActual value was `"$($get.$key)`"`n"
}
}
$Reason = [reason]::new()
$Reason.code = $this.GetType().Name + ':' + $this.GetType().Name + ':Configuration'
$phrase = "The machine returned the following configuration details.`n`n"
$phrase += "`tSettings in desired state:`n$state0`n"
$phrase += "`tSettings not in desired state:`n$state1"
$phrase += "`n$additionalText"
$Reason.phrase = $phrase
$return = @()
$return += $Reason
return $return
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment