Powershell and the registry

 

This page is a follow up to my web page about Powershell modules and the path that Powershell follows to find modules that are installed on a computer.

Powershell has an environment variable $envPSModulePath that defines the path - but some of the contents of the variable are actually stored in the registry in a value of the Environment subkey with the registry path of

HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

The value is called PSModulePath and contains a string that shows some of the locations in the file system in which Powershell modules are stored.

The interaction between Powershell and the registry goes further than this - because Powershell is equipped with Providers - Providers are .NET programmes that are a sort of layer that sits between the Powershell cmdlets and a data store.

The Provider allows the cmdlets that are usually used to manage files and directories to manage the components of the data store.

The Powershell command

Get-PSProvider

shows the Providers that are installed on the computer.

The Powershell command

Get-PSDrive

shows a list of drives that have been created by Providers in addition to the normal file system drives.

The registry is a data store, and one of the Providers - the registry Provider - allows the file management cmdlets to manage the keys, sub-keys, values and data in the registry.

The registry Provider allows Powershell to define two of the root keys of the registry as drives which behave like the normal drives such as C:\ or D:\ - these root keys are HKLM and HKCU.

As these are now regarded as drives the commands

Set-Location -Path HKLM:\

or

Set-Location -Path HKCU:\

allows Powershell to use these as root locations for further management within the registry.

So we can drill down into the registry with commands like

Set-Location -Path HKLM:\SYSTEM\

or

Set-Location -Path HKLM:\SYSTEM\CurrentControlSet\

or

Set-Location -Path HKLM:\SYSTEM\CurrentControlSet\Control\

Now there is a problem because the next sub-key - Session Manager - has a space in it, and this will upset Powershell - so the whole path has to be wrapped in quotes -

Set-Location -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\"

Then we can use the Get-ChildItem cmdlet to output all the registry keys in the current hive with their properties -

Get-ChildItem

This shows all the sub-keys ( including Environment ) and all their values.

The command

Get-ChildItem | Select-Object Name

shows just the list of sub keys, without all the values and data.

To look into the Environment sub-key, the command

Get-ItemProperty -Path Environment

shows the values and data of the Environment sub-key, including the PSModulePath value and the data string.

Drilling down further into the Environment sub-key -

Set_Location -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\"

allows the use of the command

Get-ItemProperty -Path .

The dot indicates the current directory, and this gives all the values and data of the Environment sub-key plus various bits of Powershell data.

Getting more selective now, and the command

Get-ItemProperty -Path . -Name PSModulePath

gives data for the value PSModulePath plus various bits of Powershell data.

The command

Get-ItemPropertyValue -Path . -Name PSModulePath

gives data for value PSModulePath without the various bits of Powershell data.

 

Adding new keys

The following commands will set up a new set of keys and sub-keys and supply a parameter and value to the subkey -

Set-Location -Path HKCU:\

New-Item -Path . -Name MyKeys

Set-Location -Path HKCU:\MyKeys

New-Item -Path . -Name NewKey1

Set-Location -Path HKCU:\MyKeys\NewKey1

New-ItemProperty -Path . -Name NewValue1 -Value NewString1 -PropertyType "String"

Check that the new keys and the parameter are all there -

Get-ItemPropertyValue -Path . -Name NewValue1

 

Renaming a key

Set-Location -Path HKCU:\

Rename-Item -Path HKCU:\MyKeys -NewName MyKeys1

 

Modifying a string

As already seen, environment paths such as PSModulePath are recorded as strings in the registry - so if you want to change the path you have to modify the string.

There are scripts published on various web pages about how to modify a string which is the value of a key parameter - this is the sort of script that I found :-

$oldpath = Get-ItemProperty -Path HKCU:\Environment -Name Path

$newpath = $oldpath.Path += ";C:\new\path"

Set-ItemProperty -Path HKCU:\Environment -Name Path -Value $newpath

I couldn`t find enough information on the web to fully understand how that script works so didn`t use it.

Instead I developed my own sequence of commands which worked for the modification I wanted to make, which was to add another string to the existing string.

It uses two variables $oldvalue and $newvalue.

Define the path to the specific key NewKey1 -

Set-Location -Path HKCU:\MyKeys1\NewKey1

Create the $oldvalue variable and put in the existing string that is in the parameter NewValue1 -

$oldvalue = Get-ItemPropertyValue -Path . -Name NewValue1

Check that that the variable $oldvalue contains the existing string -

$oldvalue

The following command creates the $newvalue variable which contains the contents of $oldvalue plus the new string -

$newvalue = $oldvalue += ";NewString2"

Check that that the variable $newvalue contains the existing string plus the new string -

$newvalue

Change the value of the NewValue1 parameter -

Set-ItemProperty -Path . -Name NewValue1 -Value $newvalue

Check that the registry has been updated -

Get-ItemPropertyValue -Path . -Name NewValue1

Compressing my set of commands down to form a three line script shows that it isn`t all that different to the script on the web -

$oldvalue = Get-ItemPropertyValue -Path . -Name NewValue1

$newvalue = $oldvalue += ";NewString2"

Set-ItemProperty -Path . -Name NewValue1 -Value $newvalue

But there are two significant differences - in the first line they used the Powershell cmdlet Get-ItemProperty - I used the Powershell cmdlet Get-ItemPropertyValue.

In the second line they have added .Path to the name of the variable $oldpath.

As far as I can work out from both the internet and from playing on the Powershell console :-

So it looks as if it is like the dot notation in languages like C, C++, and Python, which is used for direct member selection - also known as the direct member access operator.

 

Other cmdlets

The registry Provider supports various other file and directory cmdlets - including commands like

Move-Item

Remove-Item

Remove-ItemProperty

Clear-ItemProperty

However I didn`t want to run the risk of damaging the registry so I gave them a miss.

 

 

 

 

 

website design by ron-t

 

website hosting by freevirtualservers.com

 

© 2024   Ron Turner

 

+                                   +  

 

Link to the W3C website.   Link to the W3C website.