Last active
August 5, 2022 13:48
-
-
Save mgreenegit/394693f4b6b8adc7ece0adfb23c4b5c0 to your computer and use it in GitHub Desktop.
TODO: add enum for gposetting type, try splitting details into a reasons array
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-Resource { | |
param( | |
[DscProperties]$DscProperties | |
) | |
$psPath = Join-Path ([System.Environment]::SystemDirectory) 'WindowsPowerShell\v1.0\powershell.exe' | |
& $psPath -noProfile -command { | |
param( | |
$Name | |
) | |
$Env:PSModulePath += ";$PSHOME\Modules\NetSecurity" | |
$NetFirewallProfile = Get-NetFirewallProfile -Name $Name | |
$get = @{} | |
$propertiesToNotReturn = @('Caption','Description','InstanceId','ElementName','PSComputerName','CimClass','CimInstanceProperties','CimSystemProperties') | |
$propertiesToReturn = $NetFirewallProfile.psobject.properties | Where-Object { $_.MemberType -in @('Property','ScriptProperty') -AND $_.Name -notin $propertiesToNotReturn } | ForEach-Object {$_.Name} | |
$propertiesToReturn | ForEach-Object {$get[$_] = [string]$NetFirewallProfile.$_} | |
return $get | |
} -arg $DscProperties.Name | |
} | |
function Set-Resource { | |
param( | |
[DscProperties]$DscProperties | |
) | |
$DscPropertiesAsJson = $DscProperties | ConvertTo-Json | |
$psPath = Join-Path ([System.Environment]::SystemDirectory) 'WindowsPowerShell\v1.0\powershell.exe' | |
& $psPath -noProfile -command { | |
param( | |
$DscPropertiesAsJson | |
) | |
$DscProperties = $DscPropertiesAsJson | ConvertFrom-Json | |
$Set = @{} | |
$DscProperties | ForEach-Object {$property = $_; if ($null -ne $DscProperties.$property) {$Set[$property] = [string]$DscProperties.$property}} | |
$Env:PSModulePath += ";$PSHOME\Modules\NetSecurity" | |
Set-NetFirewallProfile @Set | |
} -arg $DscPropertiesAsJson | |
} | |
function Test-Resource { | |
param( | |
[DscProperties]$DscProperties | |
) | |
$test = $false | |
$Get = Get-Resource -DscProperties $DscProperties | |
$propertiesWithValues = $DscProperties.psobject.properties | Where-Object {$_.Value -ne $null} | ForEach-Object {$_.Name} | |
$Compare = Compare-Object -ReferenceObject $Get -DifferenceObject $DscProperties -Property $propertiesWithValues | |
if ($Compare.count -eq 0) { $test = $true } | |
return $test | |
} | |
class DscProperties { | |
[DscProperty(Key)] | |
[string] $Name | |
[DscProperty()] | |
[string] $Enabled | |
[DscProperty()] | |
[string] $DefaultInboundAction | |
[DscProperty()] | |
[string] $DefaultOutboundAction | |
[DscProperty()] | |
[string] $AllowInboundRules | |
[DscProperty()] | |
[string] $AllowLocalFirewallRules | |
[DscProperty()] | |
[string] $AllowLocalIPsecRules | |
[DscProperty()] | |
[string] $AllowUserApps | |
[DscProperty()] | |
[string] $AllowUserPorts | |
[DscProperty()] | |
[string] $AllowUnicastResponseToMulticast | |
[DscProperty()] | |
[string] $NotifyOnListen | |
[DscProperty()] | |
[string] $EnableStealthModeForIPsec | |
[DscProperty()] | |
[string] $LogFileName | |
[DscProperty()] | |
[string] $LogMaxSizeKilobytes | |
[DscProperty()] | |
[string] $LogAllowed | |
[DscProperty()] | |
[string] $LogBlocked | |
[DscProperty()] | |
[string] $LogIgnored | |
[DscProperty()] | |
[string] $DisabledInterfaceAliases | |
} | |
########## No need to edit below this line ########## | |
function Get-AdditionalText { | |
param ( | |
$get | |
) | |
$text = "Additional information:" | |
foreach ($property in ($get.Keys | sort-object)) { | |
$text += "`n`t[i] $property`: $([string]$get.$property)" | |
} | |
return $text | |
} | |
class Reason { | |
[DscProperty()] | |
[string] $Code | |
[DscProperty()] | |
[string] $Phrase | |
} | |
[DscResource()] | |
class NetSecurityDsc : DscProperties { | |
[DscProperty(NotConfigurable)] | |
[Reason[]]$Reasons | |
[NetSecurityDsc] Get() { | |
# Splat properties to Get function | |
$DscProperties = $this.GetConfigurableDscProperties() | |
$get = Get-Resource $DscProperties | |
# Adds Reasons to get | |
$additionalText = Get-AdditionalText -get $get | |
$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 ($null -ne $DscProperties.$key) { | |
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