Powershell/Private/RegistryKey/Set-DATFilePermission.ps1

function Set-DATFilePermission {
    param (
        [Parameter(Mandatory = $true)]
        [System.String]
        $Path,
        [Parameter(Mandatory = $true)]
        [System.String]
        $Username,
        [Parameter(Mandatory = $true)]
        [ValidateSet("registry", "ntfs")]
        [System.String]
        $Type
    )

    begin {
        $userSid = Convert-UserName -user "$($Env:ComputerName)\$Username"
        $requiredIdentities = @(
            'S-1-5-18',     # NT AUTHORITY\SYSTEM
            'S-1-5-32-544', # BUILTIN\Administrators
            $userSid
        )
    }

    process {
        $registryKey = $null
        try {
            if ($Type -eq 'registry') {
                # Prefer disposable .NET handles over Get-Acl/Set-Acl on HKEY_USERS:
                # which can leave provider handles that block REG UNLOAD.
                $subKey = ConvertTo-UsersRegistrySubKey -Path $Path
                $regRights = [System.Security.AccessControl.RegistryRights]::ChangePermissions -bor `
                    [System.Security.AccessControl.RegistryRights]::ReadKey -bor `
                    [System.Security.AccessControl.RegistryRights]::WriteKey
                $permCheck = [Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree
                $registryKey = [Microsoft.Win32.Registry]::Users.OpenSubKey($subKey, $permCheck, $regRights)
                if ($null -eq $registryKey) {
                    throw "Unable to open registry key for permission update: $subKey"
                }
                $acl = $registryKey.GetAccessControl()
            } else {
                $acl = Get-Acl -Path $Path
            }

            $isProtected = $acl.AreAccessRulesProtected
            $modified = $false

            foreach ($identitySid in $requiredIdentities) {
                $existingRules = @($acl.Access | Where-Object {
                        try {
                            $ruleSid = $_.IdentityReference.Translate([System.Security.Principal.SecurityIdentifier]).Value
                        } catch {
                            $ruleSid = $_.IdentityReference.Value
                        }
                        $ruleSid -eq $identitySid
                    })
                $hasValidAllow = $false

                foreach ($rule in $existingRules) {
                    if ($rule.AccessControlType -eq 'Deny') {
                        $acl.RemoveAccessRule($rule) | Out-Null
                        $modified = $true
                        Write-ToLog -Message "Set-DATFilePermission: Removed Deny rule for $identitySid on $Path" -Level Verbose
                        continue
                    }

                    $rightsValid = if ($Type -eq 'registry') {
                        $rule.RegistryRights -contains 'FullControl'
                    } else {
                        $rule.FileSystemRights -contains 'FullControl'
                    }

                    if ($rightsValid) {
                        $hasValidAllow = $true
                    } else {
                        $acl.RemoveAccessRule($rule) | Out-Null
                        $modified = $true
                        Write-ToLog -Message "Set-DATFilePermission: Removed insufficient Allow rule for $identitySid on $Path" -Level Verbose
                    }
                }

                if (-not $hasValidAllow) {
                    $sidObj = New-Object System.Security.Principal.SecurityIdentifier($identitySid)
                    if ($Type -eq 'registry') {
                        $newRule = New-Object System.Security.AccessControl.RegistryAccessRule(
                            $sidObj, 'FullControl', 'Allow'
                        )
                    } else {
                        $newRule = New-Object System.Security.AccessControl.FileSystemAccessRule(
                            $sidObj, 'FullControl', 'Allow'
                        )
                    }
                    $acl.SetAccessRule($newRule)
                    $modified = $true
                    Write-ToLog -Message "Set-DATFilePermission: Added Allow FullControl for $identitySid on $Path" -Level Verbose
                }
            }

            if ($modified) {
                $acl.SetAccessRuleProtection($isProtected, $false)
                if ($Type -eq 'registry') {
                    $registryKey.SetAccessControl($acl)
                } else {
                    Set-Acl -Path $Path -AclObject $acl
                }
            }
        } catch {
            Write-ToLog -Message "Set-DATFilePermission: Failed to update permissions on $Path : $($_.Exception.Message)" -Level Warning
            return $false
        } finally {
            if ($null -ne $registryKey) {
                $registryKey.Close()
                $registryKey.Dispose()
            }
        }

        $valid, $null = Test-DATFilePermission -Path $Path -Username $Username -Type $Type
        return $valid
    }
}