Set-Acl : Requested registry access is not allowed

2 powershell

After reading this question and this blog post I came up with these commands

Set-Location HKLM:\Software\Classes\cmdfile\ShellEx\PropertySheetHandlers
$am = New-Object Security.Principal.NTAccount 'BUILTIN', 'Administrators'
$ke = Get-Acl 'ShimLayer Property Page'
$ke.SetOwner($am)
Set-Acl -AclObject $ke -Path 'ShimLayer Property Page'
Run Code Online (Sandbox Code Playgroud)

However when I run them I get this message

Set-Acl : Requested registry access is not allowed.
Run Code Online (Sandbox Code Playgroud)

How can I change the owner of this key?

小智 5

看完这些

将密钥所有者更改为管理员

设置对 TrustedInstaller 拥有的文件的控制

我想出了这个可行的解决方案。

Function Enable-Privilege {
  param($Privilege)
  $Definition = @'
using System;
using System.Runtime.InteropServices;
public class AdjPriv {
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
    ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr rele);
  [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
  internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
  [DllImport("advapi32.dll", SetLastError = true)]
  internal static extern bool LookupPrivilegeValue(string host, string name,
    ref long pluid);
  [StructLayout(LayoutKind.Sequential, Pack = 1)]
  internal struct TokPriv1Luid {
    public int Count;
    public long Luid;
    public int Attr;
  }
  internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
  internal const int TOKEN_QUERY = 0x00000008;
  internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
  public static bool EnablePrivilege(long processHandle, string privilege) {
    bool retVal;
    TokPriv1Luid tp;
    IntPtr hproc = new IntPtr(processHandle);
    IntPtr htok = IntPtr.Zero;
    retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
      ref htok);
    tp.Count = 1;
    tp.Luid = 0;
    tp.Attr = SE_PRIVILEGE_ENABLED;
    retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
    retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero,
      IntPtr.Zero);
    return retVal;
  }
}
'@
  $ProcessHandle = (Get-Process -id $pid).Handle
  $type = Add-Type $definition -PassThru
  $type[0]::EnablePrivilege($processHandle, $Privilege)
}

do {} until (Enable-Privilege SeTakeOwnershipPrivilege)
$key = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey(
  'Software\Classes\cmdfile\ShellEx\PropertySheetHandlers\ShimLayer Property Page',
  'ReadWriteSubTree', 'TakeOwnership')
$owner = [Security.Principal.NTAccount]'Administrators'
$acl = $key.GetAccessControl()
$acl.SetOwner($owner)
$key.SetAccessControl($acl)
Run Code Online (Sandbox Code Playgroud)