Tagged: registry
Working with the Windows Registry with Powershell 4.0
I figured I would rehash some of the learning I did on working with the registry with PowerShell. Most of my research on this topic was on a couple technet pages:
- http://technet.microsoft.com/en-us/library/dd315270.aspx
- http://technet.microsoft.com/en-us/library/dd315394.aspx
There is nothing really new here, just trying to commit what I learned at technet to my brain.
WARNING: Editing your registry is dangerous. Make sure you know what your doing, document your changes, and have a backup so you can revert when you mess up.
The first interesting tidbit I learned was that PowerShell looks at the registry like it is a drive and working with the registry is similar to working with files and folders. The big difference is all of the keys are treated like folders and the registry entries and values are properties on the key. So, there is no concept of a file when working with the registry.
Viewing Registry Keys
Just like working with the file system in PowerShell, we can use the powerful Get-ChildItem command.
PS> Get-ChildItem -Path hkcu:\
Interesting right? hkcu is the HKEY_CURRENT_USER registry and its treated like a drive with all of its keys as folders under the drive. Actually, hkcu is a PowerShell drive.
PowerShell Drives
PowerShell creates a data store for PowerShell drives and this allows you to work with the registry like you do the file system.
If you want to view a list of the PowerShell drives in your session run the Get-PSDrive command.
PS> Get-PSDrive
Did you notice the other drives like Variable and Env? Can you think of a reason to use the Env drive to get access to Path or other variables?
Since we are working with a drive we can achieve the same results that we did with Get-Children with basic command line syntax.
PS> cd hkcu:\
PS> dir
Path Aliases
We can also represent the path with the registry provider name followed by “::” registry. The registry provider name is Microsoft.Powershell.Core\Registry and can be shortened to Registry. The previous example can be written as:
PS> Get-ChildItem -Path Microsoft.Powershell.Core\Registry::HKEY_CURRENT_USER
PS> Get-ChildItem -Path Registry::HKCU
The first syntax is much easier, but having the provider is more verbose and explicit in what is happening (less comments in the code to explain what’s happening).
More Get-ChildItem Goodies
The examples above only list the top level keys under the path. If you want to list all keys you can use the -Recurse parameter, but if you do this on a path with many keys you will be in for a long wait.
PS> Get-ChildItem -Path Registry::HKCU -Recurse
We can use the Set-Location command to set the location of the registry. With a location set we can use “.” in the path to refer to the current location and “..” for the parent folder.
PS> Set-Location -Path Registry::HKCU\Environment
PS> Get-ChildItem -Path .
PS> Get-ChildItem -Path ..\Keyboard Layout
Above, we set the location to the Environment key, then we get the items for the key using only “.” as the path, then we get the items in another key using the “..” to represent the parent key and indicating the key under the parent we want to get items for.
When using Get-ChildItem on the registry we have its parameters at our disposal, like Path, Filter, Include, and Exclude. Since these parameter only work against names we have to use more powerful cmdlet’s to get more meaningful filtering done. In the example provide on technet, we are able to get all keys under HKCU:\Software with no more than one subkey and exactly four values:
PS> Get-ChildItem -Path HKCU:\Software -Recurse | Where-Object -FilterScript { ($_.SubKeyCount -le 1) -and ($_.ValueCount -eq 4) }
Working with Registry Keys
As we saw registry keys are PowerShell items. So, we can use other PowerShell item commands. Keep in mind that you can represent the paths in any of the ways that we already covered.
Copy Keys
Copy a key to another location.
PS> Copy-Item -Path Registry::HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion -Destination Registry::HKCU -Recurse
This copies the keys in the Path to the Destination. Since we added Recurse all of the keys, not just the top level, will be copied.
Creating Keys
Create a new key.
PS> New-Item -Path Registry::HKCU\_DeleteMe
Deleting Keys
Delete a key.
PS> Remove-Item -Path Registry::HKCU\_DeleteMe\* -Recurse
This will remove all items under _DeleteMe. \* is telling PowerShell to delete the items, but keep the container. If we didn’t use \* the container, _DeleteMe, would be removed too. -Recurse will remove all items in the container, not just the top level items. If we attempted to remove without adding the -Recurse parameter and the item has child items we would get a warning that we are about to remove the item and all of its children. -Recurse hides that message.
Working with Registry Entries
Working with registry keys is simple because we get to use the knowledge we know about working with the file system in PowerShell. One problem is that registry entries are represented as properties of registry key items. So, we have to do a little more work to deal with entries.
List Entries
The easiest way, IMHO, to view registry entries is with Get-ItemProperty.
PS> Get-ItemProperty -Path Registry::HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion
This will list all of the properties for the key with PowerShell related keys prefixed with “PS”.
Get Single Entry
To get a single entry we use the same Get-ItemProperty and add a Name property to specify the entry we want to return.
PS> Get-ItemProperty -Path HKLM:\Software\Microsoft\Windows\CurrentVersion -Name DevicePath
This will return just the DevicePath entry along with the related PS properties.
Create New Entry
We can add a new registry key entry with the New-ItemProperty command.
PS> New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -PropertyType String -Value $PSHome
A little more complexity to this operation, but still not rocket science. We added two more properties. PropertyType signifies the type of property to create and it must be a Microsoft.Win32.RegistryValueKind (how to deal with 64bit is something I haven’t dealt with so I leave it to you for now). Value in the example uses a PowerShell value $PSHome which is the install directory of PowerShell. You can use your own values or variables for -Value.
PropertyType Value | Meaning |
---|---|
Binary | Binary data |
DWord | A number that is a valid UInt32 |
ExpandString | A string that can contain environment variables that are dynamically expanded |
MultiString | A multiline string |
String | Any string value |
QWord | 8 bytes of binary data |
Rename Entry
To rename an entry just specify the current name and the new name.
PS> Rename-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -NewName PSHome -passthru
NewName is the new name for the entry. The passthru parameter is optional and it is used to display the renamed value.
Delete Entry
To delete an entry just specify the name.
PS> Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PSHome
Conclusion
Is it really this easy? Why yes it is young Padawan…yes it is. You too can control the force to destroy your registry with PowerShell :).