I have found a behaviour in Powershell that looks very inconsistent and confusing to me, it is mainly about different notations when accessing registry keys, and what kind of syntax is expected (as an argument) or delivered (as a return value) by various commandlets, especially loke this:
HKEY_LOCAL_MACHINE... vs. HKLM:\
Let me show you an example:
$baseDir = "HKLM:\System\CurrentControlSet\Enum\SCSI"
$Results = Get-ChildItem $baseDir -Recurse -ErrorAction SilentlyContinue
foreach ($item in $Results)
{
$Subkey = $item.Name
$keyExists = Test-Path "$Subkey" -PathType Container -ErrorAction SilentlyContinue
if ($keyExists -eq $False)
{
New-Item $Subkey
}
}
So what happens is the following:
$Subkey = $item.Name
returns HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\SCSI\SomePath
and
$keyExists = Test-Path "$Subkey" -PathType Container -ErrorAction SilentlyContinue
fails to work with that syntax, i.e. returns "$false" even though the path exists.
I have, as a workaround, entered the followng line of code between these two lines, which fixes the problem:
$Subkey = $Subkey -replace "HKEY_LOCAL_MACHINE", "HKLM:"
That works - it alters the string to: HKLM:\System\CurrentControlSet\Enum\SCSI\SomePath so Test-Path can work with that syntax, but it is not very elegant.
What am I actually missing? Why does powershell not return the Result-names from Get-ChildItem in a way that is suitable for further processing in powershell? Why not always use the same syntax style?
To me, this is a design flaw in Powershell, or is there any other way to fix that?
(Note: this is only a stripped-down example to show the basic problem, I know that it doesn't make sense to search for child items and check it's existence...)
HKLM:
is a valid PSDrive while HKEY_LOCAL_MACHINE
is not.
PS C:\> Get-PSProvider Registry | select -Expand Drives
Name Used (GB) Free (GB) Provider Root CurrentLocation
---- --------- --------- -------- ---- ---------------
HKLM Registry HKEY_LOCAL_MACHINE
HKCU Registry HKEY_CURRENT_USER
Use Test-Path
on the items' PSPath
property instead of their Name
property.