Thanks to PowerShells universal “Provider” concept, you can navigate the Windows Registry just as you would the file system. In this chapter, you will learn how to read and write Registry keys and Registry values.
The Registry stores many crucial Windows settings. That’s why it’s so cool to read and sometimes change information in the Windows Registry: you can manage a lot of configuration settings and sometimes tweak Windows in ways that are not available via the user interface.
However, if you mess things up – change the wrong values or deleting important settings – you may well permanently damage your installation. So, be very careful, and don’t change anything that you do not know well.
Using Providers
To access the Windows Registry, there are no special cmdlets. Instead, PowerShell ships with a so-called provider named “Registry”. A provider enables a special set of cmdlets to access data stores. You probably know these cmdlets already: they are used to manage content on drives and all have the keyword “item” in their noun part:
PS> Get-Command -Noun Item*
CommandType Name ModuleName Definition
----------- ---- ---------- ----------
Cmdlet Clear-Item Microsoft.PowerSh... ...
Cmdlet Clear-ItemProperty Microsoft.PowerSh... ...
Cmdlet Copy-Item Microsoft.PowerSh... ...
Cmdlet Copy-ItemProperty Microsoft.PowerSh... ...
Cmdlet Get-Item Microsoft.PowerSh... ...
Cmdlet Get-ItemProperty Microsoft.PowerSh... ...
Cmdlet Invoke-Item Microsoft.PowerSh... ...
Cmdlet Move-Item Microsoft.PowerSh... ...
Cmdlet Move-ItemProperty Microsoft.PowerSh... ...
Cmdlet New-Item Microsoft.PowerSh... ...
Cmdlet New-ItemProperty Microsoft.PowerSh... ...
Cmdlet Remove-Item Microsoft.PowerSh... ...
Cmdlet Remove-ItemProperty Microsoft.PowerSh... ...
Cmdlet Rename-Item Microsoft.PowerSh... ...
Cmdlet Rename-ItemProperty Microsoft.PowerSh... ...
Cmdlet Set-Item Microsoft.PowerSh... ...
Cmdlet Set-ItemProperty Microsoft.PowerSh... ...
Many of these cmdlets have historic aliases, and when you look at those, the cmdlets probably become a lot more familiar:
PS> Get-Alias -Definition *-Item*
CommandType Name ModuleName Definition
----------- ---- ---------- ----------
Alias cli Clear-Item
Alias clp Clear-ItemProperty
Alias copy Copy-Item
Alias cp Copy-Item
Alias cpi Copy-Item
Alias cpp Copy-ItemProperty
Alias del Remove-Item
Alias erase Remove-Item
Alias gi Get-Item
Alias gp Get-ItemProperty
Alias ii Invoke-Item
Alias mi Move-Item
Alias move Move-Item
Alias mp Move-ItemProperty
Alias mv Move-Item
Alias ni New-Item
Alias rd Remove-Item
Alias ren Rename-Item
Alias ri Remove-Item
Alias rm Remove-Item
Alias rmdir Remove-Item
Alias rni Rename-Item
Alias rnp Rename-ItemProperty
Alias rp Remove-ItemProperty
Alias si Set-Item
Alias sp Set-ItemProperty
Thanks to the “Registry” provider, all of these cmdlets (and their aliases) can also work with the Registry. So if you wanted to list the keys of
HKEY_LOCAL_MACHINE\Software, this is how you’d do it:
Dir HKLM:\Software
Available Providers
Get-PSProvider gets a list of all available providers. Your list can easily be longer than in the following example. Many PowerShell extensions add additional providers. For example, the ActiveDirectory module that ships with Windows Server 2008 R2 (and the RSAT tools for Windows 7) adds a provider for the Active Directory. Microsoft SQL Server (starting with 2007) comes with an SQLServer provider.
Get-PSProvider
Name Capabilities Drives
---- ------------ ------
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem filter, ShouldProcess {C, E, S, D}
function ShouldProcess {function}
Registry ShouldProcess {HKLM, HKCU}
Variable ShouldProcess {Variable}
Certificate ShouldProcess {cert}
What’s interesting here is the “Drives” column, which lists the drives that are managed by a respective provider. As you see, the registry provider manages the drives
HKLM: (for the registry root HKEY_LOCAL_MACHINE) and HKCU: (for the registry root HKEY_CURRENT_USER). These drives work just like traditional file system drives. Check this out:
Cd HKCU:
Dir
Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER
SKC VC Name Property
--- -- ---- --------
2 0 AppEvents {}
7 1 Console {CurrentPage}
15 0 Control Panel {}
0 2 Environment {TEMP, TMP}
4 0 EUDC {}
1 6 Identities {Identity Ordinal, Migrated7, Last ...
3 0 Keyboard Layout {}
0 0 Network {}
4 0 Printers {}
38 1 Software {(default)}
2 0 System {}
0 1 SessionInformation {ProgramCount}
1 8 Volatile Environment {LOGONSERVER, USERDOMAIN, USERNAME,...
You can navigate like in the file system and dive deeper into subfolders (which here really are registry keys).
Provider |
Description |
Example |
Alias |
Manages aliases, which enable you to address a command under another name. You’ll learn more about aliases in Chapter 2. |
Dir Alias: $alias:Dir |
Environment |
Provides access to the environment variables of the system. More in Chapter 3. |
Dir env: $env:windir |
Function |
Lists all defined functions. Functions operate much like macros and can combine several commands under one name. Functions can also be an alternative to aliases and will be described in detail in Chapter 9. |
Dir function: $function:tabexpansion |
FileSystem |
Provides access to drives, directories and files. |
Dir c: $(c:\autoexec.bat) |
Registry |
Provides access to branches of the Windows registry. |
Dir HKCU: Dir HKLM: |
Variable |
Manages all the variables that are defined in the PowerShell console. Variables are covered in Chapter 3. |
Dir variable: $variable:pshome |
Certificate |
Provides access to the certificate store with all its digital certificates. These are examined in detail in Chapter 10. |
Dir cert: Dir cert: -recurse |
Table 16.2: Default providers
Creating Drives
PowerShell comes with two drives built-in that point to locations in the Windows Registry: HKLM: and HKCU:.
Get-PSDrive -PSProvider Registry
Name Provider Root CurrentLocation
---- -------- ---- ---------------
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
That’s a bit strange because when you open the Registry Editor regedit.exe, you’ll see that there are more than just two root hives.
If you wanted to access another hive, let’s say HKEY_USERS, you’d have to add a new drive like this:
New-PSDrive -Name HKU -PSProvider Registry -Root HKEY_USERS
Dir HKU:
You may not have access to all keys due to security settings, but your new drive HKU: works fine. Using New-PSDrive, you now can access all parts of the Windows Registry.
To remove the drive, use Remove-PSDrive (which only works if HKU: is not the current drive in your PowerShell console):
Remove-PSDrive HKU
You can of course create additional drives that point to specific registry keys that you may need to access often.
New-PSDrive InstalledSoftware registry 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall'
Dir InstalledSoftware:
Note that PowerShell drives are only visible inside the session you defined them. Once you close PowerShell, they will automatically get removed again.
To keep additional drives permanently, add the New-PSDrive statements to your profile script so they get automatically created once you launch PowerShell.
Using Provider Names Directly
Actually, you do not need PowerShell drives at all to access the Registry. In many scenarios, it can be much easier to work with original Registry paths. To make this work, prepend the paths with the provider names like in the example below:
Dir HKLM:\Software
Dir Registry::HKEY_LOCAL_MACHINE\Software
Dir Registry::HKEY_USERS
Dir Registry::HKEY_CLASSES_ROOT\.ps1
With this technique, you can even list all the Registry hives:
Dir Registry::
Searching for Keys
Get-ChildItem can list all subkeys of a key, and it can of course use recursion to search the entire Registry for keys with specific keywords.
The registry provider doesn’t support filters, though, so you cannot use the parameter -Filter when you search the registry. Instead, use -Include and -Exclude. For example, if you wanted to find all Registry keys that include the word “PowerShell”, you could search using:
PS> Get-ChildItem HKCU:, HKLM: -Recurse -Include *PowerShell* -ErrorAction SilentlyContinue |
>> Select-Object -ExpandProperty Name
>>
HKEY_CURRENT_USER\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe
HKEY_CURRENT_USER\Software\Microsoft\PowerShell
HKEY_CURRENT_USER\Software\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell
Note that this example searches both HKCU: and HKLM:. The error action is set to SilentlyContinue because in the Registry,
you will run into keys that are access-protected and would raise ugly “Access Denied” errors. All errors are suppressed that way.
Searching for Values
Since Registry values are not interpreted as separate items but rather are added to keys as so-called ItemProperties, you cannot use Get-ChildItem to search for Registry values. You can search for values indirectly, though. Here is some code that finds all Registry keys that have at least one value with the keyword “PowerShell”:
PS> Get-ChildItem HKCU:, HKLM: -Recurse -ea 0 | Where-Object { $_.GetValueNames() |
>> Where-Object { $_ -like '*PowerShell*' } }
If you want to find all keys that have a value with the keyword in its data, try this:
PS> Get-ChildItem HKCU:, HKLM: -Recurse -ea 0 | Where-Object { $key = $_; $_.GetValueNames() |
>> ForEach-Object { $key.GetValue($_) } | Where-Object { $_ -like '*PowerShell*' } }
Reading One Registry Value
If you need to read a specific Registry value in a Registry key, use Get-ItemProperty. This example reads the registered owner:
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name RegisteredOwner
RegisteredOwner : Tim Telbert
PSPath : Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion
PSParentPath : Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT
PSChildName : CurrentVersion
PSDrive : HKLM
PSProvider : Registry
Unfortunately, the Registry provider adds a number of additional properties so you don’t get back the value alone.
Add another Select-Object to really get back only the content of the value you are after:
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -Name RegisteredOwner |
>> Select-Object -ExpandProperty RegisteredOwner
Tim Telbert
Reading Multiple Registry Values
Maybe you’d like to read more than one Registry value. Registry keys can hold an unlimited number of values. The code is not much different from before. Simply replace the single Registry value name with a comma-separated list, and again use Select-Object to focus only on those. Since this time you are reading multiple properties, use -Property instead of –ExpandProperty parameter.
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' `
>> -Name ProductName, EditionID, CSDVersion, RegisteredOwner |
>> Select-Object -Property ProductName, EditionID, CSDVersion, RegisteredOwner
>>
ProductName EditionID CSDVersion RegisteredOwner
----------- --------- ---------- ---------------
Windows 7 Ultimate Ultimate Service Pack 1 Tim Telbert
Or, a little simpler:
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' |
>> Select-Object -Property ProductName, EditionID, CSDVersion, RegisteredOwner
>>
ProductName EditionID CSDVersion RegisteredOwner
----------- --------- ---------- ---------------
Windows 7 Ultimate Ultimate Service Pack 1 Tim Telbert
Reading Multiple Keys and Values
Yet maybe you want to read values not just from one Registry key but rather a whole bunch of them. In HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall, you find a lot of keys, one for each installed software product. If you wanted to get a list of all software installed on your machine, you could read all of these keys and display some values from them.
That again is just a minor adjustment to the previous code because Get-ItemProperty supports wildcards. Have a look:
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' |
>> Select-Object -Property DisplayName, DisplayVersion, UninstallString
DisplayName DisplayVersion UninstallString
----------- -------------- ---------------
0.8.2.232
Microsoft IntelliPoint 8.1 8.15.406.0 msiexec.exe /I {3ED4AD...
Microsoft Security Esse... 2.1.1116.0 C:\Program Files\Micro...
NVIDIA Drivers 1.9 C:\Windows\system32\nv...
WinImage "C:\Program Files\WinI...
Microsoft Antimalware 3.0.8402.2 MsiExec.exe /X{05BFB06...
Windows XP Mode 1.3.7600.16422 MsiExec.exe /X{1374CC6...
Windows Home Server-Con... 6.0.3436.0 MsiExec.exe /I{21E4979...
Idera PowerShellPlus Pr... 4.0.2703.2 MsiExec.exe /I{7a71c8a...
Intel(R) PROSet/Wireles... 13.01.1000
(...)
Voilá, you get a list of installed software. Some of the lines are empty, though. This occurs when a key does not have the value you are looking for.
To remove empty entries, simply add Where-Object like this:
PS> Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' |
>> Select-Object -Property DisplayName, DisplayVersion, UninstallString |
>> Where-Object { $_.DisplayName -ne $null }
Creating Registry Keys
Since Registry keys are treated like files or folders in the file system, you can create and delete them accordingly. To create new keys, either use historic aliases like md or mkdir, or use the underlying cmdlet directly:
PS> New-Item HKCU:\Software\NewKey1
Hive: Registry::HKEY_CURRENT_USER\Software
Name Property
---- --------
NewKey1
PS> md HKCU:\Software\NewKey2
Hive: Registry::HKEY_CURRENT_USER\Software
Name Property
---- --------
NewKey2
If a key name includes blank characters, enclose the path in quotation marks. The parent key has to exist.
To create a new key with a default value, use New-Item and specify the value and its data type:
PS> New-Item HKCU:\Software\NewKey3 -Value 'Default Value Text' -Type String
Hive: Registry::HKEY_CURRENT_USER\Software
Name Property
---- --------
NewKey3 (default) : Default Value Text
Deleting Registry Keys
To delete a key, use the historic aliases from the file system that you would use to delete a folder, or use the underlying cmdlet Remove-Item directly:
PS> Remove-Item HKCU:\Software\Test1
Del HKCU:\Software\Test2
Del HKCU:\Software\Test3
This process needs to be manually confirmed if the key you are about to remove contains other keys:
Del HKCU:\Software\KeyWithSubKeys
Confirm
The item at "HKCU:\Software\KeyWithSubKeys" has children and the Recurse parameter was not specified.
if you continue, all children will be removed with the item. Are you sure you want to continue?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Use the –Recurse parameter to delete such keys without manual confirmation:
Del "HKCU:\Software\First key" -Recurse
Creating Values
Each Registry key can have an unlimited number of values. Earlier in this chapter, you learned how to read these values. Values are called “ItemProperties”, so they belong to an “Item”, the Registry key.
To add new values to a Registry key, either use New-ItemProperty or Set-ItemProperty. New-ItemProperty cannot overwrite an existing value and returns the newly created value in its object form. Set-ItemProperty is more easy going. If the value does not yet exist, it will be created, else changed. Set-ItemProperty does not return any object.
Here are some lines of code that first create a Registry key and then add a number of values with different data types:
PS> New-Item HKCU:\Software\TestKey4
PS> Set-ItemProperty HKCU:\Software\TestKey4 -Name Name -Value 'Smith'
PS> Set-ItemProperty HKCU:\Software\TestKey4 -Name ID -Value 12 -Type DWORD
PS> Set-ItemProperty HKCU:\Software\TestKey4 -Name Path -Value '%WINDIR%' -Type ExpandString
PS> Set-ItemProperty HKCU:\Software\TestKey4 -Name Notes -Value 'First Note','Second Note' `
>> -Type MultiString
>>
PS> Set-ItemProperty HKCU:\Software\TestKey4 -Name DigitalInfo -Value 4,8,12,200,90 -Type Binary
PS> Get-ItemProperty HKCU:\Software\TestKey4
Name : Smith
ID : 12
Path : C:\Windows
Notes : {First Note, Second Note}
DigitalInfo : {4, 8, 12, 200...}
PSPath : Registry::HKEY_CURRENT_USER\Software\TestKey4
PSParentPath : Registry::HKEY_CURRENT_USER\Software
PSChildName : TestKey4
PSDrive : HKCU
PSProvider : Registry
If you wanted to set the keys’ default value, use ‘(default)’ as value name.
ItemType |
Description |
DataType |
String |
A string |
REG_SZ |
ExpandString |
A string with environment variables that are resolved when invoked |
REG_EXPAND_SZ |
Binary |
Binary values |
REG_BINARY |
DWord |
Numeric values |
REG_DWORD |
MultiString |
Text of several lines |
REG_MULTI_SZ |
QWord |
64-bit numeric values |
REG_QWORD |
Table 16.4: Permitted ItemTypes in the registry
Use Remove-ItemProperty to remove a value. This line deletes the value Name value that you created in the previous example:
Remove-ItemProperty HKCU:\Software\Testkey4 Name
Clear-ItemProperty clears the content of a value, but not the value itself.
Be sure to delete your test key once you are done playing:
Remove-Item HKCU:\Software\Testkey4 -Recurse
Securing Registry Keys
Registry keys (and its values) can be secured with Access Control Lists (ACLs) in pretty much the same way the NTFS file system manages access permissions to files and folders. Likewise, you can use Get-Acl to show current permissions of a key:
md HKCU:\Software\Testkey4
Get-Acl HKCU:\Software\Testkey
Path Owner Access
---- ----- ------
Microsoft.PowerShell.Core\Registr... TobiasWeltne-PC\Tobias Weltner TobiasWeltne-PC\Tobias Weltner A...
To apply new security settings to a key, you need to know the different access rights that can be assigned to a key. Here is how you get a list of these rights:
PS> [System.Enum]::GetNames([System.Security.AccessControl.RegistryRights])
QueryValues
SetValue
CreateSubKey
EnumerateSubKeys
Notify
CreateLink
Delete
ReadPermissions
WriteKey
ExecuteKey
ReadKey
ChangePermissions
TakeOwnership
FullControl
Taking Ownership
Always make sure that you are the “owner” of the key before modifying Registry key access permissions. Only owners can recover from lock-out situations, so if you set permissions wrong, you may not be able to undo the changes unless you are the owner of the key.
This is how to take ownership of a Registry key (provided your current access permissions allow you to take ownership. You may want to run these examples in a PowerShell console with full privileges):
$acl = Get-Acl HKCU:\Software\Testkey
$acl.Owner
scriptinternals\TobiasWeltner
$me = [System.Security.Principal.NTAccount]"$env:userdomain\$env:username"
$acl.SetOwner($me)
Setting New Access Permissions
The next step is to assign new permissions to the key. Let’s exclude the group “Everyone” from making changes to this key:
$acl = Get-Acl HKCU:\Software\Testkey
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"WriteKey"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Deny"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.AddAccessRule($rule)
Set-Acl HKCU:\Software\Testkey $acl
The modifications immediately take effect.Try creating new subkeys in the Registry editor or from within PowerShell, and you’ll get an error message:
md HKCU:\Software\Testkey\subkey
New-Item : Requested Registry access is not allowed.
At line:1 char:34
+ param([string[]]$paths); New-Item <<<< -type directory -path $paths
Why does the restriction applies to you as an administrator? Aren’t you supposed to have full access?
No, restrictions always have priority over permissions, and because everyone is a member of the Everyone group, the restriction applies to you as well. This illustrates that you should be extremely careful applying restrictions. A better approach is to assign permissions only.
Removing an Access Rule
The new rule for Everyone was a complete waste of time after all because it applied to everyone, effectively excluding everyone from the key. So, how do you go about removing a rule? You can use RemoveAccessRule() to remove a particular rule, and RemoveAccessRuleAll() to remove all rules of the same type (permission or restriction) for the user named in the specified rule. ModifyAccessRule() changes an existing rule, and PurgeAccessRules() removes all rules for a certain user.
To remove the rule that was just inserted, proceed as follows:
$acl = Get-Acl HKCU:\Software\Testkey
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"WriteKey"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Deny"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.RemoveAccessRule($rule)
Set-Acl HKCU:\Software\Testkey $acl -Force
However, removing your access rule may not be as straightforward because you have effectively locked yourself out.
Since you no longer have modification rights to the key, you are no longer allowed to modify the keys’ security settings as well.
You can overrule this only if you take ownership of the key: Open the Registry editor, navigate to the key, and by right-clicking and then selecting Permissions open the security dialog box and manually remove the entry for Everyone.
You’ve just seen how relatively easy it is to lock yourself out. Be careful with restriction rules.
Controlling Access to Sub-Keys
In the next example, you use permission rules rather than restriction rules. The task: create a key where only administrators can make changes. Everyone else should just be allowed to read the key.
md HKCU:\Software\Testkey2
$acl = Get-Acl HKCU:\Software\Testkey2
# Admins may do everything:
$person = [System.Security.Principal.NTAccount]”Administrators”
$access = [System.Security.AccessControl.RegistryRights]"FullControl"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Allow"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.ResetAccessRule($rule)
# Everyone may only read and create subkeys:
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"ReadKey"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"None"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Allow"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.ResetAccessRule($rule)
Set-Acl HKCU:\Software\Testkey2 $acl
Note that in this case the new rules were not entered by using AddAccessRule() but by ResetAccessRule().
This results in removal of all existing permissions for respective users. Still, the result isn’t right because regular users could still create subkeys and write values:
md hkcu:\software\Testkey2\Subkey
Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\software\Testkey2
SKC VC Name Property
--- -- ---- --------
0 0 Subkey {}
Set-ItemProperty HKCU:\Software\Testkey2 Value1 "Here is text"
Revealing Inheritance
Look at the current permissions of the key to figure out why your permissions did not work the way you planned:
(Get-Acl HKCU:\Software\Testkey2).Access | Format-Table -Wrap
RegistryRights AccessControlType IdentityReference IsInherited InheritanceFlags PropagationFlags
-------------- ----------------- ----------------- ----------- ---------------- ----------------
ReadKey Allow Everyone False None None
FullControl Allow BUILT-in\Admi False None None
nistrators
FullControl Allow TobiasWeltne-PC\T True ContainerInherit, None
obias Weltner ObjectInherit
FullControl Allow NT AUTHORITY\SYST True ContainerInherit, None
EM ObjectInherit
FullControl Allow BUILT-in\Admi True ContainerInherit, None
nistrators ObjectInherit
ReadKey Allow NT AUTHORITY\REST True ContainerInherit, None
RICTED ACCESS ObjectInherit
The key includes more permissions than what you assigned to it. It gets these additional permissions by inheritance from parent keys.
If you want to turn off inheritance, use SetAccessRuleProtection():
$acl = Get-Acl HKCU:\Software\Testkey2
$acl.SetAccessRuleProtection($true, $false)
Set-Acl HKCU:\Software\Testkey2 $acl
Now, when you look at the permissions again, the key now contains only the permissions you explicitly set. It no longer inherits any permissions from parent keys:
RegistryRights AccessControlType IdentityReference IsInherited InheritanceFlags PropagationFlags
-------------- ----------------- ----------------- ----------- ---------------- ----------------
ReadKey Allow Everyone False None None
FullControl Allow BUILT-in\Admistrators False None None
Controlling Your Own Inheritance
Inheritance is a sword that cuts both ways. You have just turned off the inheritance of permissions from parent keys, but will your own newly set permissions be propagated to subkeys? Not by default. If you want to pass on your permissions to subdirectories, change the setting for propagation, too. Here are all steps required to secure the key:
del HKCU:\Software\Testkey2
md HKCU:\Software\Testkey2
$acl = Get-Acl HKCU:\Software\Testkey2
# Admins may do anything:
$person = [System.Security.Principal.NTAccount]”Administrators”
$access = [System.Security.AccessControl.RegistryRights]"FullControl"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Allow"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.ResetAccessRule($rule)
# Everyone may only read and create subkeys:
$person = [System.Security.Principal.NTAccount]"Everyone"
$access = [System.Security.AccessControl.RegistryRights]"ReadKey"
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]"None"
$type = [System.Security.AccessControl.AccessControlType]"Allow"
$rule = New-Object System.Security.AccessControl.RegistryAccessRule(`
$person,$access,$inheritance,$propagation,$type)
$acl.ResetAccessRule($rule)
Set-Acl HKCU:\Software\Testkey2 $acl
Like this:
Số lượt thích Đang tải...