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.
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
Set-Location -Path HKCU:\
Rename-Item -Path HKCU:\MyKeys -NewName MyKeys1
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.
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.