Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

Registry: Resource needs to delete all values under a key #63

Open
zjalexander opened this issue May 19, 2017 · 3 comments
Open

Registry: Resource needs to delete all values under a key #63

zjalexander opened this issue May 19, 2017 · 3 comments
Labels
enhancement The issue is an enhancement request. in progress The issue is being actively worked on by someone.

Comments

@zjalexander
Copy link

This scenario is from Bobby Reed for the Baseline Management scenario.
Group Policies sometimes have a *delval command which clears all values under a key and then inserts a new key.

Imagine if I allowed a compromised and outdated cipher suite in the Registry Key. Without **delval, DSC would never catch it, as it would just ensure that the ALLOWED cipher suites were present. GROUP POLICY however, WOULD catch it because it is still processing the **delval properly.

That made me think of another discussion @kwirkykat had for the SecurityPolicy module: dsccommunity/SecurityPolicyDsc#28 (comment)

I think the Registry resource needs something like an explicit “Include”/"Exclude" parameter along the lines the Group parameter Katie describes: https://github.com/powershell/psdscresources#group

@bobbytreed
Copy link

bobbytreed commented May 30, 2017

I’m re-thinking this slightly. I think this has to be an “Exclusive” property.

In the UserRightsAssignment resource you can use FORCE to ensure that only the members specified are members of the right, I think we should mirror that.

The reason why is that a MembersToInclude/Exclude will look very strange in a Registry Key resource block. The Group example only requires a string array because you just need to specify member names.

THIS KeysToInclude will need to contain a Registry Key Definition for Every instance.

Consider these examples:

Registry Test
{
   Key = "HKLM:\Software\Microsoft\7-Zip"
    # This is a KEY property so it has to be specified which makes it then odd to have to specify Member to Include as well.
    ValueName = "FastCompression"
    ValueData = 1
    ValueType = DWORD 
    # This just feels clunky because you would have to pass a valuename above because it's a key, but then you could specify other values as well? That would make it hard to troubleshoot.
    MembersToInclude = @(
        
        @{
            ValueName = "HighValue"
            ValueData = 1
            ValueType = DWORD
        }, 
        "AnotherValue" # So it should create another ValueName? Which ValueData etc.?
    )
    MembersToExclude = @(
        # Why should I need to specify all of this information, but if I don't it won't be consistent with above.
        @{
            ValueName = "Offset"
            ValueData = 1
            ValueType = DWORD
        }
        ,* # The Group Property doesn't accept wildcards, but this one would have to, it's the whole purpose of the change.
    )
}

Registry Test
{
    Key = "HKLM:\Software\Microsoft\7-Zip"
    ValueName = "FastCompression"
    ValueData = 1
    ValueType = DWORd
    Exclusive = $true # Could go with other names as well, but basically a property saying that this should be the only value in this key.
}

Registry Test
{
    Key = "HKLM:\Software\Microsoft\7-Zip"
    ValueName = "" # Even though Value Name is a Key, it can still be blank.  This has typically been used to remove a key.
    Exclusive = $true # Now this would wipe all values out of a key without erasing the key.
} 

Whether it's "Enforce", "Exclusive" or another word, I think a Flag is the best way to go. I have already successfully implemented an "Exclusive" flag and I am working on the Pester Tests now.

@kwirkykat kwirkykat added the enhancement The issue is an enhancement request. label Jun 1, 2017
@VertigoRay
Copy link

VertigoRay commented Apr 16, 2018

@bobbytreed Can you put all of your code in a codeblock (with ```powershell). I imagine the middle got code blocked due to indentation, but your example is hard enough to read that I pasted it into a text editor.

I'm currently looking at this because I have a couple functions that I'm considering either breaking out into a RegistryPlus resource, or I'd like to see the feature implemeted as part of the actual Registry module.

My current implementation using a Script resource uses an AllowedValues property to provide a string[] of allowed Value Names that should be left alone, the rest deleted. You can see it here.

I agree that your initial example feels clunky. Then again, I feel like the implementation of ValueName as an empty string to target a Key is a bit clunky. This is a topic for a separate issue though.

I think an ideal implementation of removing excess registry Key Values would look something like this:

Registry 7Zip_FastCompression
{
    Key = 'HKLM:\Software\Microsoft\7-Zip'
    ValueName = 'FastCompression'
    ValueData = 1
    ValueType = 'DWORD'
}

Registry 7Zip_HighValue
{
    Key = 'HKLM:\Software\Microsoft\7-Zip'
    ValueName = 'HighValue'
    ValueData = 1
    ValueType = 'DWORD'
}

Registry 7Zip_RemoveExcessValueNames
{
    Key = 'HKLM:\Software\Microsoft\7-Zip'
    ValueName = '' # Ideally without this property
    RemoveExcessValueNames = $true
    DependsOn = @(
        '[Registry]7Zip_FastCompression',
        '[Registry]7Zip_HighValue'
    )
}

You could then do something like this to pull the Key/Value information out of the other Registry Resources based on the DependsOn value:

<#
    $Key, $DependsOn, and $RemoveExcessValueNames are from the respective
    `[Registry]7Zip_RemoveExcessValueNames` property
#>

if ($DependsOn)
{
    $DependentResources = Get-DscConfiguration `
        | Where-Object { $DependsOn -contains $_.ResourceId.Split(':')[0] }

    if ($DependentResources.ResourceId.StartsWith('[Registry]') -contains $false)
    {
        Throw "When using RemoveExcessValueNames, all resources referenced in DependsOn must be Registry resources."
    }

    if (($DependentResources.key | Sort-Object -Unique).Count -ne 1)
    {
        Throw "When using RemoveExcessValueNames, Registry resources referenced in DependsOn must all have the same Key."
    }

    if ($DependentResources.key[0] -ne $Key)
    {
        Throw "When using RemoveExcessValueNames, Registry resources referenced in DependsOn must have the same key as this resource."
    }
}

$AllowedValueNames = $DependentResources.ValueName
$RegKey = Get-Item -LiteralPath $Key
$NotAllowedValues = $RegKey.Property `
    | Where-Object { $AllowedValueNames -notcontains $_ }

foreach ($Value in $NotAllowedValues)
{
    Remove-ItemProperty -LiteralPath $Key -Name $Value -Force
}

Code logic should remove all values if a DependsOn is not supplied. I can work on a PR, but would like to know if my direction is amiable. Specifically the use of Get-DscConfiguration ... which I know won't work from a machine that's not applying these configs. I just am not real sure where to begin with exploring what DSC sees during building of a MOF file. 😏

Update: 2018 Apr 18

I'm looking through the work that @dlwyatt has done in DscFix, but I'm still reverse engineering his functions to try to figure out how he's able to check the properties of Resources for conflicts. Maybe Dave can provide some insight on how to best go about this?

Update: 2018 Apr 19

I'm not having luck implementing this because DependsOn isn't made available to Set-TargetResource or Test-TargetResource. Attempted to make it available in the schema.mof by adding this as a property descriptor:

[Write, Description("Make DependsOn available.")] String DependsOn[];

Unfortunately, it seemed to ignore that I was now asking for it. I could implement it like this:

Registry Test_RemoveExcessValueNames
{
    Key = 'HKLM:\Software\Microsoft\7-Zip'
    ValueName = '' # Ideally without this property
    RemoveExcessValueNames = @(
        'FastCompression',
        'HighValue'
    )
    DependsOn = @(
        '[Registry]Test_FastCompression',
        '[Registry]Test_HighValue'
    )
}

However, that's not very DRY. 😒

@johlju johlju added the in progress The issue is being actively worked on by someone. label Apr 30, 2018
@johlju
Copy link
Contributor

johlju commented Apr 30, 2018

This is being worked on in PR #64.

@johlju johlju changed the title Registry resource needs to delete all values under a key Registry: Resource needs to delete all values under a key Apr 30, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement The issue is an enhancement request. in progress The issue is being actively worked on by someone.
Projects
None yet
Development

No branches or pull requests

5 participants