PowerShell · lesson 6 of 12
PSDrives and the Registry as a Filesystem
PowerShell's provider model makes the registry navigable with Get-ChildItem, cd, and Test-Path — except Get-ChildItem lists subkeys, not values, which looks like an empty key until you reach for Get-ItemProperty instead.
By SkillByExample · Published
cd works on the registry. That single fact is what PowerShell’s provider model buys you —
and it’s also where the first gotcha in this lesson comes from.
Everything is a drive
Get-PSDrive | Select-Object Name, Provider
Name Provider
---- --------
Alias Microsoft.PowerShell.Core\Alias
C Microsoft.PowerShell.Core\FileSystem
Cert Microsoft.PowerShell.Security\Certificate
Env Microsoft.PowerShell.Core\Environment
Function Microsoft.PowerShell.Core\Function
HKCU Microsoft.PowerShell.Core\Registry
HKLM Microsoft.PowerShell.Core\Registry
Temp Microsoft.PowerShell.Core\FileSystem
Variable Microsoft.PowerShell.Core\Variable
WSMan Microsoft.WSMan.Management\WSMan
C: and HKCU: are both just drives backed by different providers — one is the file
system, one is the registry, and the same cmdlets (Get-ChildItem, Test-Path, Remove-Item)
work against either. This is why HKCU: and HKLM: look exactly like drive letters: as far
as the cmdlets are concerned, they are.
Creating and reading a value
New-Item -Path "HKCU:\Software\PowerShellLessonDemo" -Force | Out-Null
Set-ItemProperty -Path "HKCU:\Software\PowerShellLessonDemo" -Name "Environment" -Value "staging"
HKCU (the current user’s hive) is safe to write test keys into — it affects only this user
account and needs no elevated permissions, unlike HKLM, which is machine-wide.
The bug: Get-ChildItem shows nothing
Get-ChildItem "HKCU:\Software\PowerShellLessonDemo"
Empty. Not an error — just nothing. The value was definitely set in the step above, so this looks like the write silently failed.
The fix: Get-ItemProperty reads values, not subkeys
Get-ItemProperty -Path "HKCU:\Software\PowerShellLessonDemo"
Environment : staging
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\PowerShellLessonDemo
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software
PSChildName : PowerShellLessonDemo
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry
There it is. Get-ChildItem on a registry path lists child keys — the registry’s version
of subfolders — and this key has none, so it correctly reported an empty list. The value lives
directly on the key, and Get-ItemProperty is what reads that. This is the single most
common point of confusion in scripting the registry: Get-ChildItem behaving like a real,
working ls that just happens to always show nothing for a key with no subkeys of its own.
Real subkeys work with Get-ChildItem as expected
Get-ChildItem "HKCU:\Software" | Select-Object -First 5 -Property PSChildName
PSChildName
-----------
4kdownload.com
Adobe
Android Open Source Project
AOMEI
appdatalow
Every one of these is a subkey, so Get-ChildItem lists them correctly — the confusion only
happens with a key’s own values, never with its child keys.
Cleanup
Remove-Item -Path "HKCU:\Software\PowerShellLessonDemo" -Force
Test-Path "HKCU:\Software\PowerShellLessonDemo"
False
Remove-Item on a registry key works exactly like deleting a file or folder — the same
cmdlet, the same -Force, a different provider underneath.
Practice
1. Create a nested subkey, then list it correctly with Get-ChildItem.
New-Item -Path "HKCU:\Software\PowerShellLessonDemo" -Force | Out-Null
New-Item -Path "HKCU:\Software\PowerShellLessonDemo\SubKey" -Force | Out-Null
Get-ChildItem "HKCU:\Software\PowerShellLessonDemo" | Select-Object PSChildName
PSChildName
-----------
SubKey
This time Get-ChildItem finds something, because SubKey really is a child key — not a
value sitting directly on the parent, which is exactly the distinction the bug above turned
on.
2. Read a single named value directly with Get-ItemPropertyValue, skipping the wrapper object.
Set-ItemProperty -Path "HKCU:\Software\PowerShellLessonDemo" -Name "Environment" -Value "staging"
Get-ItemPropertyValue -Path "HKCU:\Software\PowerShellLessonDemo" -Name "Environment"
staging
No PSPath, no PSDrive, none of Get-ItemProperty’s metadata clutter — just the value
itself, useful when a script only ever needs the one thing.
3. Try removing the demo tree without -Recurse first, then with it.
Remove-Item -Path "HKCU:\Software\PowerShellLessonDemo" -Force
Remove-Item: PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
A key with a subkey and no -Recurse makes Remove-Item stop and ask “this has children, are
you sure?” — in a script or a non-interactive session, there’s nothing to answer that prompt,
so it errors out instead of guessing.
Remove-Item -Path "HKCU:\Software\PowerShellLessonDemo" -Recurse -Force
Test-Path "HKCU:\Software\PowerShellLessonDemo"
False
-Recurse answers that question up front — delete the key and everything under it, no prompt
needed.
Next: error handling — terminating versus non-terminating errors, and why -ErrorAction Stop matters.