Powershell – Besitzer eines Registry Keys ändern / übernehmen

Über die Registry werden unter Windows viele Dinge gesteuert. Doch was macht man, wenn in der Registrierung Einträge geändert werden müssen / sollen, auf welche selbst der locale Admin keinen Zugriff hat? Ich hatte das Problem beim TrustInstaller, dessen Version auf dem PC neuer war – als die Version welche im entsprechenden Registry-Key hinterlegt war. Ich den Key aber nicht ändern konnte, da mir die Rechte dafür gefehlt haben. So habe ich überlegt, wie man die Rechte am einfachsten ändern könnte.

Als Lösungsansatz könnte ich mir die Powershell vorstellen, welche sich immer anbietet – wenn Dinge im Herzen von Windows geändert werden sollen.

Ich muss auch ganz ehrlich gestehen – das Skript ist ein Schnipsel welches ich selbst gefunden habe, nachdem ich fast an der Programmierung von Powershell verzweifelt bin. Aber wie auch immer – es funktioniert sehr sauber und zuverlässig.

Bei mir ging es darum folgenden Wert in der Registrierung zu übernehmen:

SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Version

Dieser Wert ist unter LocalMaschine zu finden.

WICHTIG!
Grundsätzlich muss der hier hinterlegte Key natürlich geändert werden und evt. auch das Script angepasst werden, wenn der Key sich nicht unter LocalMachine befindet. Diese Änderung kann relativ weit unten im Script vorgenommen werden.

Der Key wird dabei als Variable (keypath) hinterlegt und der Ort muss im Script angepasst werden. HKLM ziemlich weit unten nicht vergessen!

Kommen wir nun zum Powershell Script mit dessen Hilfe man die Rechte auf Schlüssel in der Registry ändern kann.

## Original P/Invoke.NET - leicht modifiziert 
$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;
  }
}
'@
# Take ownership privilege
$ProcessHandle = (Get-Process -id $pid).Handle
$type = Add-Type $definition -PassThru
$max_retry=10
for ($i=1; $i -le $max_retry;$i++){
    $status=$type[0]::EnablePrivilege($processHandle, "SeTakeOwnershipPrivilege")
    if ($status){break}
    if ($i -eq $max_retry){read-host "Unable to take ownership privilege";exit}
    start-sleep 1|out-null
    }
#
$keypath="SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Version"
#
# Get localized admin group name
$admin=(get-wmiobject win32_group| Where-Object {$_.sid -eq "s-1-5-32-544"}).name
# Change Owner to the local Administrators group
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("$keypath", "ReadWriteSubTree", "TakeOwnership")
$regACL = $regKey.GetAccessControl()
$regACL.SetOwner([System.Security.Principal.NTAccount]"$admin")
$regKey.SetAccessControl($regACL)
# Change Permissions for the local Administrators group
$regKey = [Microsoft.Win32.Registry]::LocalMachine.OpenSubKey("$keypath", "ReadWriteSubTree", "ChangePermissions")
$regACL = $regKey.GetAccessControl()
$regRule = New-Object System.Security.AccessControl.RegistryAccessRule ("$admin","FullControl","ContainerInherit","None","Allow")
$regACL.SetAccessRule($regRule)
# Change Permissions for System
$regRule = New-Object System.Security.AccessControl.RegistryAccessRule ("SYSTEM","SetValue","ContainerInherit","None","Deny")
$regACL.SetAccessRule($regRule)
$regKey.SetAccessControl($regACL)
New-ItemProperty -Path "HKLM:$keyPath" -Name "Enabled" -Value 1 -PropertyType DWORD -Force |out-null

Wir hoffen, Euch hilft das Skript bei den Änderungen in der Registry so perfekt wie mir!

Die mobile Version verlassen