Tests/Unit/cNtfsPermissionEntry.Tests.ps1

#requires -Version 4.0 -Modules Pester, CimCmdlets

$Global:DSCModuleName   = 'cNtfsAccessControl'
$Global:DSCResourceName = 'cNtfsPermissionEntry'

#region Header

$ModuleRoot = Split-Path -Path $Script:MyInvocation.MyCommand.Path -Parent | Split-Path -Parent | Split-Path -Parent

if (
    (-not (Test-Path -Path (Join-Path -Path $ModuleRoot -ChildPath 'DSCResource.Tests') -PathType Container)) -or
    (-not (Test-Path -Path (Join-Path -Path $ModuleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -PathType Leaf))
)
{
    & git @('clone', 'https://github.com/PowerShell/DscResource.Tests.git', (Join-Path -Path $ModuleRoot -ChildPath 'DSCResource.Tests'))
}

Import-Module -Name (Join-Path -Path $ModuleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force

$TestEnvironment = Initialize-TestEnvironment `
    -DSCModuleName $Global:DSCModuleName `
    -DSCResourceName $Global:DSCResourceName `
    -TestType Unit

#endregion

try
{
    #region Unit Tests

    InModuleScope $Global:DSCResourceName {

        #region Helper Functions

        function Set-NewTempItemAcl
        {
            <#
            .SYNOPSIS
                Creates a new temporary directory or file and sets its Access Control List (ACL).
 
            .DESCRIPTION
                The Set-NewTempItemAcl function creates a new temporary directory or file and sets its Access Control List (ACL):
                - Disables NTFS permissions inheritance.
                - Removes all permission entries.
                - Grants Full Control permission to the calling user to ensure the file can be removed later.
                - Optionally adds additional permission entries.
            #>

            [CmdletBinding()]
            param
            (
                [Parameter(Mandatory = $false)]
                [ValidateSet('Directory', 'File')]
                [String]
                $ItemType = 'Directory',

                [Parameter(Mandatory = $false)]
                [ValidateNotNullOrEmpty()]
                [String]
                $Path = (Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())),

                [Parameter(Mandatory = $false)]
                [System.Security.AccessControl.FileSystemAccessRule[]]
                $AccessRulesToAdd,

                [Parameter(Mandatory = $false)]
                [Switch]
                $PassThru
            )

            try
            {
                $TempItem = New-Item -Path $Path -ItemType $ItemType -Force -ErrorAction Stop -Verbose:$VerbosePreference
                $Acl = $TempItem.GetAccessControl()

                $Acl.SetAccessRuleProtection($true, $false)
                $Acl.Access.ForEach({[Void]$Acl.RemoveAccessRule($_)})

                $CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name

                if ($ItemType -eq 'Directory')
                {
                    $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $CurrentUser,
                            'FullControl',
                            @('ContainerInherit',
                            'ObjectInherit'),
                            'None',
                            'Allow'
                        )
                }
                else
                {
                    $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $CurrentUser,
                            'FullControl',
                            'None',
                            'None',
                            'Allow'
                        )
                }

                $Acl.AddAccessRule($DefaultAccessRule)

                if ($PSBoundParameters.ContainsKey('AccessRulesToAdd'))
                {
                    $AccessRulesToAdd.ForEach({$Acl.AddAccessRule($_)})
                }

                if ($ItemType -eq 'Directory')
                {
                    [System.IO.Directory]::SetAccessControl($TempItem.FullName, $Acl)
                }
                else
                {
                    [System.IO.File]::SetAccessControl($TempItem.FullName, $Acl)
                }

                if ($PassThru)
                {
                    return $TempItem
                }
            }
            catch
            {
                throw
            }
        }

        #endregion

        Describe "$Global:DSCResourceName\Get-TargetResource" {

            Context 'Permissions exist' {

                $ContextParams = @{
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                $Result = Get-TargetResource @ContextParams

                It 'Should return Ensure set to Present' {
                    $Result.Ensure | Should Be 'Present'
                }

                It 'Should return Path' {
                    $Result.Path | Should Be $ContextParams.Path
                }

                It 'Should return Principal' {
                    $Result.Principal | Should Be $ContextParams.Principal
                }

                It 'Should return AccessControlInformation' {
                    $Result.AccessControlInformation.Count | Should Be 3
                }

            }

            Context 'No permissions exist' {

                $ContextParams = @{
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                $Result = Get-TargetResource @ContextParams

                It 'Should return Ensure set to Absent' {
                    $Result.Ensure | Should Be 'Absent'
                }

                It 'Should return Path' {
                    $Result.Path | Should Be $ContextParams.Path
                }

                It 'Should return Principal' {
                    $Result.Principal | Should Be $ContextParams.Principal
                }

                It 'Should return empty AccessControlInformation' {
                    $Result.AccessControlInformation.Count | Should Be 0
                }

            }

        }

        Describe "$Global:DSCResourceName\Test-TargetResource behavior with Ensure set to Absent" {

            Context 'AccessControlInformation is not specified, no permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                It 'Should return True' {
                    Test-TargetResource @ContextParams | Should Be $true
                }

            }

            Context 'AccessControlInformation is not specified, permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is specified, no matching permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return True' {
                    Test-TargetResource @ContextParams | Should Be $true
                }

            }

            Context 'AccessControlInformation is specified, matching permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

        }

        Describe "$Global:DSCResourceName\Test-TargetResource behavior with Ensure set to Present" {

            Context 'AccessControlInformation is not specified, no permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is not specified, default permission exists, no other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $ContextParams.Principal,
                        'ReadAndExecute',
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        'Allow'
                    )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $DefaultAccessRule

                It 'Should return True' {
                    Test-TargetResource @ContextParams | Should Be $true
                }

            }

            Context 'AccessControlInformation is not specified, default permission exists, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $ContextParams.Principal,
                        'ReadAndExecute',
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        'Allow'
                    )

                $TempAccessRules = @(

                    $DefaultAccessRule

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is not specified, no default permission exists, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is specified, no permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'CreateFiles', 'AppendData'
                                Inheritance = 'SubfoldersAndFilesOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is specified, desired permissions exist, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return False' {
                    Test-TargetResource @ContextParams | Should Be $false
                }

            }

            Context 'AccessControlInformation is specified, permissions exist and match the desired state' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'CreateFiles', 'AppendData'
                                Inheritance = 'SubfoldersAndFilesOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should return True' {
                    Test-TargetResource @ContextParams | Should Be $true
                }

            }

        }

        Describe "$Global:DSCResourceName\Set-TargetResource behavior with Ensure set to Absent" {

            Context 'AccessControlInformation is not specified, permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should remove all permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $TempAccessRules.Count

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be 0

                }

            }

            Context 'AccessControlInformation is specified, matching permissions exist' {

                $ContextParams = @{
                    Ensure = 'Absent'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should remove matching permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $TempAccessRules.Count

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be ($TempAccessRules.Count - $ContextParams.AccessControlInformation.Count)

                }

            }

        }

        Describe "$Global:DSCResourceName\Set-TargetResource behavior with Ensure set to Present" {

            Context 'AccessControlInformation is not specified, no permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $ContextParams.Principal,
                        'ReadAndExecute',
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        'Allow'
                    )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                It 'Should add the default permission' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be 0

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    $AccessRules = @(
                        (Get-Acl -Path $ContextParams.Path).Access.Where(
                            {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                        )
                    )

                    $AccessRules.Count | Should Be 1
                    $AccessRules[0].FileSystemRights | Should Be $DefaultAccessRule.FileSystemRights
                    $AccessRules[0].AccessControlType | Should Be $DefaultAccessRule.AccessControlType
                    $AccessRules[0].InheritanceFlags | Should Be $DefaultAccessRule.InheritanceFlags
                    $AccessRules[0].PropagationFlags | Should Be $DefaultAccessRule.PropagationFlags

                }

            }

            Context 'AccessControlInformation is not specified, default permission exists, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $ContextParams.Principal,
                        'ReadAndExecute',
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        'Allow'
                    )

                $TempAccessRules = @(

                    $DefaultAccessRule

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should remove other permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $TempAccessRules.Count

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    $AccessRules = @(
                        (Get-Acl -Path $ContextParams.Path).Access.Where(
                            {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                        )
                    )

                    $AccessRules.Count | Should Be 1
                    $AccessRules[0].FileSystemRights | Should Be $DefaultAccessRule.FileSystemRights
                    $AccessRules[0].AccessControlType | Should Be $DefaultAccessRule.AccessControlType
                    $AccessRules[0].InheritanceFlags | Should Be $DefaultAccessRule.InheritanceFlags
                    $AccessRules[0].PropagationFlags | Should Be $DefaultAccessRule.PropagationFlags

                }

            }

            Context 'AccessControlInformation is not specified, no default permission exists, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                }

                $DefaultAccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $ContextParams.Principal,
                        'ReadAndExecute',
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        'Allow'
                    )

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should add the default permission and remove other permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $TempAccessRules.Count

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    $AccessRules = @(
                        (Get-Acl -Path $ContextParams.Path).Access.Where(
                            {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                        )
                    )

                    $AccessRules.Count | Should Be 1
                    $AccessRules[0].FileSystemRights | Should Be $DefaultAccessRule.FileSystemRights
                    $AccessRules[0].AccessControlType | Should Be $DefaultAccessRule.AccessControlType
                    $AccessRules[0].InheritanceFlags | Should Be $DefaultAccessRule.InheritanceFlags
                    $AccessRules[0].PropagationFlags | Should Be $DefaultAccessRule.PropagationFlags

                }

            }

            Context 'AccessControlInformation is specified, no permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'CreateFiles', 'AppendData'
                                Inheritance = 'SubfoldersAndFilesOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path

                It 'Should add the desired permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be 0

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $ContextParams.AccessControlInformation.Count

                }

            }

            Context 'AccessControlInformation is specified, desired permissions exist, other permissions exist' {

                $ContextParams = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'ReadAndExecute'
                                Inheritance = 'ThisFolderSubfoldersAndFiles'
                                NoPropagateInherit = $false
                            }

                        New-CimInstance -ClientOnly `
                            -Namespace root/Microsoft/Windows/DesiredStateConfiguration `
                            -ClassName cNtfsAccessControlInformation `
                            -Property @{
                                AccessControlType = 'Allow'
                                FileSystemRights = 'Modify'
                                Inheritance = 'ThisFolderOnly'
                                NoPropagateInherit = $false
                            }

                    )
                }

                $TempAccessRules = @(

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'ReadAndExecute',
                            @('ContainerInherit', 'ObjectInherit'),
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            'Modify',
                            'None',
                            'None',
                            'Allow'
                        )

                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList @(
                            $ContextParams.Principal,
                            @('CreateFiles', 'AppendData'),
                            @('ContainerInherit', 'ObjectInherit'),
                            'InheritOnly',
                            'Allow'
                        )

                )

                Set-NewTempItemAcl -ItemType Directory -Path $ContextParams.Path -AccessRulesToAdd $TempAccessRules

                It 'Should remove other permissions' {

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $TempAccessRules.Count

                    Test-TargetResource @ContextParams | Should Be $false

                    Set-TargetResource @ContextParams

                    Test-TargetResource @ContextParams | Should Be $true

                    (Get-Acl -Path $ContextParams.Path).Access.Where(
                        {$_.IsInherited -eq $false -and $_.IdentityReference -eq $ContextParams.Principal}
                    ).Count |
                    Should Be $ContextParams.AccessControlInformation.Count

                }

            }

        }

        Describe "$Global:DSCResourceName\ConvertFrom-FileSystemAccessRule" {

            $DescribeParams = @{
                Principal = 'BUILTIN\Users'
                AccessControlType = 'Allow'
                FileSystemRights = @('ReadAndExecute', 'Write', 'Synchronize')
            }

            Context 'PropagationFlags has the NoPropagateInherit flag set' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        @('ContainerInherit', 'ObjectInherit'),
                        'NoPropagateInherit',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return NoPropagateInherit set to True' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'ThisFolderSubfoldersAndFiles'
                    $Result.NoPropagateInherit | Should Be $true
                }

            }

            Context 'InheritanceFlags is None and PropagationFlags is None' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        'None',
                        'None',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to ThisFolderOnly if ItemType is Directory' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'ThisFolderOnly'
                    $Result.NoPropagateInherit | Should Be $false
                }

                It 'Should return Inheritance set to None if ItemType is File' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType File -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'None'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is "ContainerInherit, ObjectInherit" and PropagationFlags is None' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        @('ContainerInherit', 'ObjectInherit'),
                        'None',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to ThisFolderSubfoldersAndFiles' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'ThisFolderSubfoldersAndFiles'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is ContainerInherit and PropagationFlags is None' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        'ContainerInherit',
                        'None',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to ThisFolderAndSubfolders' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'ThisFolderAndSubfolders'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is ObjectInherit and PropagationFlags is None' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        'ObjectInherit',
                        'None',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to ThisFolderAndFiles' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'ThisFolderAndFiles'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is "ContainerInherit, ObjectInherit" and PropagationFlags is InheritOnly' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        @('ContainerInherit', 'ObjectInherit'),
                        'InheritOnly',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to SubfoldersAndFilesOnly' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'SubfoldersAndFilesOnly'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is ContainerInherit and PropagationFlags is InheritOnly' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        'ContainerInherit',
                        'InheritOnly',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to SubfoldersOnly' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'SubfoldersOnly'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

            Context 'InheritanceFlags is ObjectInherit and PropagationFlags is InheritOnly' {

                $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                    -ArgumentList @(
                        $DescribeParams.Principal,
                        $DescribeParams.FileSystemRights,
                        'ObjectInherit',
                        'InheritOnly',
                        $DescribeParams.AccessControlType
                    )

                It 'Should return Inheritance set to FilesOnly' {
                    $Result = ConvertFrom-FileSystemAccessRule -ItemType Directory -InputObject $AccessRule
                    $Result.Inheritance | Should Be 'FilesOnly'
                    $Result.NoPropagateInherit | Should Be $false
                }

            }

        }

        Describe "$Global:DSCResourceName\New-FileSystemAccessRule" {

            $DescribeParams = @{
                Principal = 'BUILTIN\Users'
                AccessControlType = 'Allow'
                FileSystemRights = @('ReadAndExecute', 'Write')
            }

            Context 'Expected behavior' {

                It 'Should return all the property values set correctly' {

                    $Result = New-FileSystemAccessRule @DescribeParams -ItemType Directory `
                        -Inheritance None -NoPropagateInherit $false

                    $Result.FileSystemRights | Should Be (
                        [System.Security.AccessControl.FileSystemRights]@(
                            $DescribeParams.FileSystemRights, 'Synchronize'
                        )
                    )

                    $Result.AccessControlType | Should Be $DescribeParams.AccessControlType
                    $Result.IdentityReference | Should Be $DescribeParams.Principal
                    $Result.IsInherited | Should Be $false
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'

                }

            }

            Context 'ItemType is Directory and NoPropagateInherit is False' {

                $ContextParams = $DescribeParams.Clone()
                $ContextParams.Add('ItemType', 'Directory')
                $ContextParams.Add('NoPropagateInherit', $false)

                It 'Inheritance is Null' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance $null
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is None' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance None
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderOnly
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderSubfoldersAndFiles' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderSubfoldersAndFiles
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderAndSubfolders' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderAndSubfolders
                    $Result.InheritanceFlags | Should Be 'ContainerInherit'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderAndFiles' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderAndFiles
                    $Result.InheritanceFlags | Should Be 'ObjectInherit'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is SubfoldersAndFilesOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance SubfoldersAndFilesOnly
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'InheritOnly'
                }

                It 'Inheritance is SubfoldersOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance SubfoldersOnly
                    $Result.InheritanceFlags | Should Be 'ContainerInherit'
                    $Result.PropagationFlags | Should Be 'InheritOnly'
                }

                It 'Inheritance is FilesOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance FilesOnly
                    $Result.InheritanceFlags | Should Be 'ObjectInherit'
                    $Result.PropagationFlags | Should Be 'InheritOnly'
                }

            }

            Context 'ItemType is Directory and NoPropagateInherit is True' {

                $ContextParams = $DescribeParams.Clone()
                $ContextParams.Add('ItemType', 'Directory')
                $ContextParams.Add('NoPropagateInherit', $true)

                It 'Inheritance is Null' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance $null
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is None' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance None
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderOnly
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

                It 'Inheritance is ThisFolderSubfoldersAndFiles' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderSubfoldersAndFiles
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is ThisFolderAndSubfolders' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderAndSubfolders
                    $Result.InheritanceFlags | Should Be 'ContainerInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is ThisFolderAndFiles' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance ThisFolderAndFiles
                    $Result.InheritanceFlags | Should Be 'ObjectInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is SubfoldersAndFilesOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance SubfoldersAndFilesOnly
                    $Result.InheritanceFlags | Should Be 'ContainerInherit, ObjectInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is SubfoldersOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance SubfoldersOnly
                    $Result.InheritanceFlags | Should Be 'ContainerInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

                It 'Inheritance is FilesOnly' {
                    $Result = New-FileSystemAccessRule @ContextParams -Inheritance FilesOnly
                    $Result.InheritanceFlags | Should Be 'ObjectInherit'
                    $Result.PropagationFlags | Should Be 'NoPropagateInherit'
                }

            }

            Context 'ItemType is File' {

                It 'Should ignore Inheritance and NoPropagateInherit' {
                    $Result = New-FileSystemAccessRule @DescribeParams -ItemType File `
                        -Inheritance ThisFolderSubfoldersAndFiles -NoPropagateInherit $true
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

            }

        }

        Describe "$Global:DSCResourceName\Set-FileSystemAccessControl" {

            $Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
            $File = New-Item -Path $Path -ItemType File
            $Acl = $File.GetAccessControl()

            $AccessRule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                -ArgumentList @(
                    'BUILTIN\Users',
                    'FullControl',
                    'None',
                    'None',
                    'Allow'
                )

            $Acl.AddAccessRule($AccessRule)

            It 'Should not throw' {
                {Set-FileSystemAccessControl -Path $Path -Acl $Acl} | Should Not Throw
            }

            It 'Should throw if Path is invalid' {
                $Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                {Set-FileSystemAccessControl -Path $Path -Acl $Acl} | Should Throw
            }

            It 'Should throw if Acl is invalid' {
                {Set-FileSystemAccessControl -Path $Path -Acl $null} | Should Throw
            }

        }

        Describe "$Global:DSCResourceName\Resolve-IdentityReference" {

            It 'Should resolve by SID' {
                $Result = Resolve-IdentityReference -Identity 'S-1-5-32-545'
                $Result.Name | Should Be 'BUILTIN\Users'
                $Result.SID | Should Be 'S-1-5-32-545'
            }

            It 'Should resolve by Name' {
                $Result = Resolve-IdentityReference -Identity 'Users'
                $Result.Name | Should Be 'BUILTIN\Users'
                $Result.SID | Should Be 'S-1-5-32-545'
            }

            It 'Should throw if Identity is invalid' {
                {Resolve-IdentityReference -Identity $null} | Should Throw
            }

            It 'Should write a non-terminating error if Identity cannot be resolved' {
                Resolve-IdentityReference -Identity 'GFawkes' -ErrorAction SilentlyContinue -ErrorVariable ResultError
                $ResultError.Count | Should Be 2
                $ResultError[1].CategoryInfo.Activity | Should Be 'Write-Error'
            }

        }

    }

    #endregion
}
finally
{
    #region Footer

    Restore-TestEnvironment -TestEnvironment $TestEnvironment

    #endregion
}