Tests/Unit/cNtfsPermissionEntry.Tests.ps1

#requires -Version 4.0 -Modules CimCmdlets, Pester

$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'))
}
else
{
    & git @('-C', (Join-Path -Path $ModuleRoot -ChildPath 'DSCResource.Tests'), 'pull')
}

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

# Begin Testing
try
{
    #region Unit Tests

    InModuleScope $Global:DSCResourceName {

        #region Helper Functions

        function Set-NewTempFileAcl
        {
            <#
            .SYNOPSYS
                Creates temporary files for unit testing of the cNtfsPermissionEntry DSC resource.
            .DESCRIPTION
                The Set-NewTempFileAcl function creates temporary files and performs the following actions on them:
                - 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)]
                [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
            {
                $File = New-Item -Path $Path -ItemType File -Force -ErrorAction Stop -Verbose:$VerbosePreference
                $Acl = $File.GetAccessControl()

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

                $CurrentUser = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
                $Acl.AddAccessRule((New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $CurrentUser, 'FullControl', 'Allow'))

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

                [System.IO.File]::SetAccessControl($File.FullName, $Acl)

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

        #endregion

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

            Context 'Expected behavior' {

                $ContextParameters = @{
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'Modify', 'Allow'
                )

                $Result = Get-TargetResource @ContextParameters

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

                It 'Should return Ensure' {
                    $Result.Ensure -in @('Absent', 'Present') | Should Be $true
                }

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

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

            }

            Context 'Permission Entry is Absent' {

                $ContextParameters = @{
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'ReadAndExecute', 'Allow'
                )

                It 'Should return Ensure set Absent' {
                    $Result = Get-TargetResource @ContextParameters
                    $Result.Ensure | Should Be 'Absent'
                }

            }

            Context 'Permission Entry is Present' {

                $ContextParameters = @{
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'Modify', 'Allow'
                )

                It 'Should return Ensure set Present' {
                    $Result = Get-TargetResource @ContextParameters
                    $Result.Ensure | Should Be 'Present'
                }

            }

        }

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

            Context 'Ensure is Absent and Permission Entry is Absent' {

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

                Set-NewTempFileAcl -Path $ContextParameters.Path

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

            }

            Context 'Ensure is Absent and Permission Entry is Present' {

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

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'Modify', 'Allow'
                )

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

            }

            Context 'Ensure is Present and Permission Entry is Present' {

                $ContextParameters = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'Modify', 'Allow'
                )

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

            }

            Context 'Ensure is Present and Permission Entry is Absent' {

                $ContextParameters = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'ReadAndExecute', 'Allow'
                )

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

            }

        }

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

            Context 'Ensure is Absent' {

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

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'Modify', 'Allow'
                )

                It 'Should remove permissions' {
                    Test-TargetResource @ContextParameters | Should Be $false
                    Set-TargetResource @ContextParameters
                    Test-TargetResource @ContextParameters | Should Be $true
                }

            }

            Context 'Ensure is Present' {

                $ContextParameters = @{
                    Ensure = 'Present'
                    Path = 'TestDrive:\' + [System.IO.Path]::GetRandomFileName()
                    Principal = 'BUILTIN\Users'
                    AccessControlInformation = @(
                        New-CimInstance -ClientOnly -Namespace 'root/Microsoft/Windows/DesiredStateConfiguration' `
                            -ClassName 'cNtfsAccessControlInformation' -Property @{FileSystemRights = 'Modify'}
                    )
                }

                Set-NewTempFileAcl -Path $ContextParameters.Path -AccessRulesToAdd @(
                    New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule `
                        -ArgumentList $ContextParameters.Principal, 'ReadAndExecute', 'Allow'
                )

                It 'Should add permissions' {
                    Test-TargetResource @ContextParameters | Should Be $false
                    Set-TargetResource @ContextParameters
                    Test-TargetResource @ContextParameters | Should Be $true
                }

            }

        }

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

            $DescribeParameters = @{
                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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    @('ContainerInherit', 'ObjectInherit'),
                    'NoPropagateInherit',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    'None',
                    'None',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    @('ContainerInherit', 'ObjectInherit'),
                    'None',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    'ContainerInherit',
                    'None',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    'ObjectInherit',
                    'None',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    @('ContainerInherit', 'ObjectInherit'),
                    'InheritOnly',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    'ContainerInherit',
                    'InheritOnly',
                    $DescribeParameters.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 @(
                    $DescribeParameters.Principal,
                    $DescribeParameters.FileSystemRights,
                    'ObjectInherit',
                    'InheritOnly',
                    $DescribeParameters.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\ConvertTo-FileSystemAccessRule" {

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

            Context 'Expected behavior' {

                It 'Should return all the property values set correctly' {
                    $Result = ConvertTo-FileSystemAccessRule @DescribeParameters -ItemType 'Directory' -Inheritance 'None' -NoPropagateInherit $false
                    $Result.FileSystemRights | Should Be ([System.Security.AccessControl.FileSystemRights]@($DescribeParameters.FileSystemRights, 'Synchronize'))
                    $Result.AccessControlType | Should Be $DescribeParameters.AccessControlType
                    $Result.IdentityReference | Should Be $DescribeParameters.Principal
                    $Result.IsInherited | Should Be $false
                    $Result.InheritanceFlags | Should Be 'None'
                    $Result.PropagationFlags | Should Be 'None'
                }

            }

            Context 'ItemType is Directory and NoPropagateInherit is False' {

                $ContextParameters = $DescribeParameters.Clone()
                $ContextParameters.Add('ItemType', 'Directory')
                $ContextParameters.Add('NoPropagateInherit', $false)

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

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

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

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

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

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

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

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

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

            }

            Context 'ItemType is Directory and NoPropagateInherit is True' {

                $ContextParameters = $DescribeParameters.Clone()
                $ContextParameters.Add('ItemType', 'Directory')
                $ContextParameters.Add('NoPropagateInherit', $true)

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

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

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

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

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

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

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

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

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

            }

            Context 'ItemType is File' {

                It 'Should ignore Inheritance and NoPropagateInherit' {
                    $Result = ConvertTo-FileSystemAccessRule @DescribeParameters -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()
            $Acl.AddAccessRule((New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList 'BUILTIN\Users', 'FullControl', 'Allow'))

            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
}