DSCResources/Grani_InheritACL/Grani_InheritACL.psm1
#region Initialize function Initialize { # Enum for Ensure try { Add-Type -TypeDefinition @" public enum EnsureType { Present, Absent } "@ } catch { } } Initialize #endregion #region Message Definition $debugMessage = DATA { ConvertFrom-StringData -StringData " CheckingPreserveInheritance = Checking acl is inherited. Access : '{0}', AccessControlType : '{1}', IsInherited : '{2}'. SettingAcl = Setting ACL to Path '{0}', IsProtected '{1}', PreserveInheritance '{2}'. " } $verboseMessage = DATA { ConvertFrom-StringData -StringData " DetectIsProtected = Path detected as Protected, means not inherited from parent. DetectIsNotProtected = Path detected as not Protected, means inherited from parent. DetectPreserveInheritance = Path detected as PreserveInheritance. GetTargetResourceDetectExeption = GetTargetResource detect exception as '{0}' ObtainACL = Path '{0}' found. Obtaining ACL. PathNotFound = Path '{0}' not found. Skip other checking. " } $exceptionMessage = DATA { ConvertFrom-StringData -StringData " PathNotFoundException = Could not found desired path '{0}' exeption! NoAccessRuleLeftException = Invalid Operation detected. there are no access left. You must set any not inherit acess before not preserve Inheritance. " } #endregion #region *-TargetResource function Get-TargetResource { [OutputType([System.Collections.Hashtable])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String]$Path, [parameter(Mandatory = $true)] [System.Boolean]$IsProtected, [parameter(Mandatory = $false)] [System.Boolean]$PreserveInheritance = $true, [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.String]$Ensure ) # Set Default value $isPathExist = $true; $returnValue = @{ Path = $Path; IsProtected = $false; PreserveInheritance = $true; }; # Path existance Check if (!(Test-Path -Path $Path)) { Write-Verbose ($verboseMessage.PathNotFound -f $Path); $isPathExist = $false; } else { try { # Obtain current ACL Write-Verbose ($verboseMessage.ObtainACL -f $Path); $acl = Get-Acl -Path $Path -ErrorAction Stop; # IsProtected Check if ($acl.AreAccessRulesProtected) { Write-Verbose ($verboseMessage.DetectIsProtected); $returnValue.IsProtected = $true; # Could not detect PreserveInheritanceCheck because this information will lost when Protected. $returnValue.PreserveInheritance = $PreserveInheritance; } else { Write-Verbose ($verboseMessage.DetectIsNotProtected); $returnValue.IsProtected = $false; # PreserveInheritanceCheck foreach ($access in $acl.Access) { Write-Debug ($debugMessage.CheckingPreserveInheritance -f $access.IdentityReference, $access.AccessControlType, $access.IsInherited); $isInherited = $access.IsInherited; if ($isInherited) { Write-Verbose ($verboseMessage.DetectPreserveInheritance); $returnValue.PreserveInheritance = $true; break; # break is fine when any access was detected inherited. } } } } catch { Write-Verbose ($verboseMessage.GetTargetResourceDetectExeption -f $_); } } # Ensure Check (Not path detected => Ensure = "Absent") if ($isPathExist -and ($IsProtected -eq $returnValue.IsProtected) -and ($PreserveInheritance -eq $returnValue.PreserveInheritance)) { $returnValue.Ensure = [EnsureType]::Present.ToString(); } else { $returnValue.Ensure = [EnsureType]::Absent.ToString(); } return $returnValue; } function Set-TargetResource { [OutputType([Void])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String]$Path, [parameter(Mandatory = $true)] [System.Boolean]$IsProtected, [parameter(Mandatory = $false)] [System.Boolean]$PreserveInheritance = $true, [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.String]$Ensure ) # Path existance Check if (!(Test-Path -Path $Path)) { throw New-Object System.IO.FileNotFoundException ($exceptionMessage.PathNotFoundException -f $Path) } # Get current $acl = Get-Acl -Path $Path; # Modify ACL Write-Debug -Message ($debugMessage -f $Path, $IsProtected, $PreserveInheritance); $acl.SetAccessRuleProtection($IsProtected, $PreserveInheritance); if (($acl.Access | sort).Count -eq 0) { throw New-Object System.InvalidOperationException ($exceptionMessage.NoAccessRuleLeftException); } # Write Back to Path $acl | Set-Acl -Path $Path } function Test-TargetResource { [OutputType([System.Boolean])] [CmdletBinding()] param ( [parameter(Mandatory = $true)] [System.String]$Path, [parameter(Mandatory = $true)] [System.Boolean]$IsProtected, [parameter(Mandatory = $false)] [System.Boolean]$PreserveInheritance = $true, [parameter(Mandatory = $false)] [ValidateSet("Present","Absent")] [System.String]$Ensure ) [bool]$result = (Get-TargetResource -Path $Path -IsProtected $IsProtected -PreserveInheritance $PreserveInheritance).Ensure -eq ([EnsureType]::Present.ToString()); return $result; } #endregion Export-ModuleMember -Function *-TargetResource |