Jacked up registry ACLs

Ok, strap in cause this might be a long one. TL:DR - former employee removes inheritance on a registry key and it can't be set back by PowerShell, only the GUI.

Background: There was an issue where Teams and Jabber were not co-existing well and Teams needed to be set as the default IM app in the IM Providers registry key. Former employee devises a proactive remediation that will accomplish this. It would appear that they were having an issue with either the system, Jabber or the users resetting Jabber to be the default app and their solution was to add some code that would set the registry ACLs to remove full control from both the User and the System account and then disable inheritance on the key to prevent any changes (code will be provided below).

Through a series of lack of proper change controls and no code review, this was put into production with no knowledge from the rest of the team that the ACLs had been fucked with. Fast forward to our attempts at upgrading to Windows 11 and we find that when we upgrade to W11, New Teams breaks. Cue 12 months of back and forth with MS Support to find the issue lies with the ACLs and our discovery of this script (since turned off).

Now to the strangeness. As a regular user, you can go into the registry and reset the ACLs, turn inheritance back on and everything works. You can delete the key and re-add it and the proper ACLs and inheritance is applied. Attempting any of that via PowerShell, either as the regular user or as System, fails. ACLs can't be changed, Inheritance can't be enabled, the key cannot be deleted. It only works when operating manually via the GUI.

I am at my wits end here and hoping someone can see something I am missing because at this point my 3 options for fixing this are: IT manually remotes into ~3K computers to fix this in the GUI, we teach the users how to fix it themselves (shudder), we wipe 3K machines and put them back through the pre-provisioning process.

function TweakReg

{

`IF(!(Test-Path $registrypath)) {`

    `New-Item -Path $registrypath -force | out-null`

    `New-ItemProperty -Path $registrypath -name $name -type $type -value $value -force | out-null`

`} ELSE {`

    `Set-ItemProperty -Path $registrypath -name $name -type $type -value $value -force | out-null`

`}` 

}

$val = Get-ItemPropertyvalue "HKCU:\SOFTWARE\IM Providers" -Name DefaultIMApp

If ($val -ne 'Teams')

{

`$registrypath = "HKCU:\SOFTWARE\IM Providers"`

`$name = "DefaultIMApp"`

`$type = "String"`

`$value = "Teams"`

`TweakReg`

}

function Disable-AclInheritance

{

<#

.SYNOPSIS

Protects an ACL so that changes to its parent can't be inherited to it.

.DESCRIPTION

Items in the registry or file system will inherit permissions from its parent. The \Disable-AclInheritnace` function disables inheritance, removing all inherited permissions. You can optionally preserve the currently inherited permission as explicit permissions using the `-Preserve` switch.`

This function is paired with \Enable-AclInheritance`.`

.LINK

Disable-AclInheritance

.LINK

Get-Permission

.LINK

Grant-Permission

.LINK

Revoke-Permission

.EXAMPLE

Disable-AclInheritance -Path C:\Projects\Carbon

Removes all inherited access rules from the \C:\Projects\Carbon` directory. Non-inherited rules are preserved.`

.EXAMPLE

Disable-AclInheritance -Path hklm:\Software\Carbon -Preserve

Stops \HKLM:\Software\Carbon` from inheriting acces rules from its parent, but preserves the existing, inheritied access rules.`

#>

[CmdletBinding(SupportsShouldProcess=$true)]

param(

[Parameter(Mandatory=$true,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]

[Alias('PSPath')]

[string]

# The file system or registry path whose access rule should stop inheriting from its parent.

$Path,

[Switch]

# Keep the inherited access rules on this item.

$Preserve

)

Set-StrictMode -Version 'Latest'

#Use-CallerPreference -Cmdlet $PSCmdlet -Session $ExecutionContext.SessionState

$acl = Get-Acl -Path $Path

if( -not $acl.AreAccessRulesProtected )

{

Write-Verbose -Message ("[{0}] Disabling access rule inheritance." -f $Path)

$acl.SetAccessRuleProtection( $true, $Preserve )

$acl | Set-Acl -Path $Path

}

}

Set-Alias -Name 'Unprotect-AclAccessRules' -Value 'Disable-AclInheritance'

Set-Alias -Name 'Protect-Acl' -Value 'Disable-AclInheritance'

IF(Test-Path 'HKCU:\SOFTWARE\IM Providers\Teams')

{

`$acl = Get-Acl 'HKCU:\SOFTWARE\IM Providers\Teams'`

`$user = whoami`

`$idRef = [System.Security.Principal.NTAccount]("$user")`

`$regRights = [System.Security.AccessControl.RegistryRights]::FullControl`

`$inhFlags = [System.Security.AccessControl.InheritanceFlags]::None`

`$prFlags = [System.Security.AccessControl.PropagationFlags]::None`

`$acType = [System.Security.AccessControl.AccessControlType]::Allow`

`$rule = New-Object System.Security.AccessControl.RegistryAccessRule ($idRef, $regRights, $inhFlags, $prFlags, $acType)`

`$acl.SetAccessRule($rule)`

`$acl | Set-Acl -Path "HKCU:\SOFTWARE\IM Providers\Teams"`



`$acl = Get-Acl 'HKCU:\SOFTWARE\IM Providers'`

`$user = whoami`

`$idRef = [System.Security.Principal.NTAccount]("$user")`

`$regRights = [System.Security.AccessControl.RegistryRights]::ReadKey`

`$inhFlags = [System.Security.AccessControl.InheritanceFlags]::None`

`$prFlags = [System.Security.AccessControl.PropagationFlags]::None`

`$acType = [System.Security.AccessControl.AccessControlType]::Allow`

`$rule = New-Object System.Security.AccessControl.RegistryAccessRule ($idRef, $regRights, $inhFlags, $prFlags, $acType)`

`$acl.SetAccessRule($rule)`

`$acl | Set-Acl -Path "HKCU:\SOFTWARE\IM Providers"`



`Disable-AclInheritance -Path "HKCU:\SOFTWARE\IM Providers"`

} else {

`write-host "Teams may not be installed"`

}