Author Posts

March 30, 2018 at 2:20 pm

I am trying to find registry keys that contain certain values. Once these keys are found, I am wanting to narrow down the search parameters looking for a specific property and value. This is where my trouble starts. You will see that I am able to perform the first search with no problem. The second search is giving me issues. I have tried a variety of methods to produce the results I am looking. Below is my current method.

$packages = Get-ChildItem -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages" -Recurse | Where-Object { ($_.Name -match $verson) } | select Name #| select -First 1

foreach ($kb in $packages) {
	Write-Host "$os"
	Write-Host "$osversion"
	Write-Host "$version"
	
	$regkey = $kb | Out-String
	$regkey = $regkey -replace "HKEY_LOCAL_MACHINE", "HKLM:"
	$regkey
	
	Get-ChildItem -Path '$regkey'
}

Error Message

Microsoft Windows 10 Pro
10.0.15063
KB4088782

Name                                                                                                                                                           
----                                                                                                                                                           
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages\Windows-Shield-Provider-Core-Package~31bf3856ad364e35~amd64~...
ERROR: Get-ChildItem : Cannot find path 'C:\Users\UserName\Documents\Powershell\$regkey' because it does not exist.
Verify Updates Installed.ps1 (41, 2): ERROR: At Line: 41 char: 2
ERROR: +     Get-ChildItem -Path '$regkey'
ERROR: +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR:     + CategoryInfo          : ObjectNotFound: (C:\Users\jmonar...ershell\$regkey:String) [Get-ChildItem], ItemNotFoundException
ERROR:     + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
ERROR:

As you can see, I am visually verifying the $regkey value but it is doing something different when searching. I think I am missing something simple. I have been dealing with several issues this week and think I just need a second pair of eyes.

March 30, 2018 at 2:28 pm

So in PowerShell, single-quoted strings and double-quoted strings are very different.

Get-ChildItem -Path '$regkey'

This attempts to look for the literal string '$regkey'.

Get-ChildItem -Path "$regkey"

This tells PS to get whatever is stored in the variable $regkey, convert it to string, and use that where it's placed in the string.

In this particular instance, you didn't need to even use quotes at all; this is perfectly fine:

Get-ChildItem -Path $regkey

Basically, use single-quoted strings when you don't want to worry about escaping characters and don't need to insert values from elsewhere. Use double-quoted strings when you need to evaluate expressions or insert variables within the string.

Of note is mixing quotes in your strings:

# The outermost quotes set the type of string:

# This won't show you the value of the variable because the string object is defined with single quotes. THe double quotation marks are just literal characters.
$LiteralString = 'this string is literal, you will not get any "$variables" in here'

# This will show you the value of the variable instead, because the string object is created with double quotes. The single quotes within are just regular characters.
$ExpandingString = "This string will show you the correct value of the variable: '$Variable'"

March 30, 2018 at 2:29 pm

Use double-quotes with variables:

"$regkey"

March 30, 2018 at 6:54 pm

I did as instructed and now have a new error for the same thing.

Name                                                                                                                                                           
----                                                                                                                                                           
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\Packages\Windows-Shield-Provider-Core-Package~31bf3856ad364e35~amd64~...
ERROR: Get-ChildItem : Cannot find drive. A drive with the name '
ERROR: Name
ERROR: ----
ERROR: HKLM' does not exist.
Verify Updates Installed.ps1 (41, 2): ERROR: At Line: 41 char: 2
ERROR: +     Get-ChildItem -Path $regkey
ERROR: +     ~~~~~~~~~~~~~~~~~~~~~~~~~~~
ERROR:     + CategoryInfo          : ObjectNotFound: (
ERROR: Name         ...
ERROR: HKLM:String) [Get-ChildItem], DriveNotFoundException
ERROR:     + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
ERROR:

March 30, 2018 at 8:56 pm

It's late in the day for me, but I think your first line is using

select name

when you need to be using

Select-Object -ExpandProperty Name

or for short:

select -exp name

I tend to advise against the shorter aliases that you can use, especially while you're learning. If you can be crystal clear in your own scripts, you'll have far fewer issues with them. 🙂

March 30, 2018 at 9:31 pm

That did the trick, thank you. BTW, not necessarily a beginner, not an expert either, but I feel like a beginner this week. Couldn't remember how to do simple things. It's been a long exhausting week.

April 4, 2018 at 11:19 am

Late to the party, HKLM:\Software contains keys that are greater than the 260 characters path limitation. How did you (if able to) handle keys that are greater than 260 characters? The error message:

Get-ChildItem : Cannot find path 'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based
Servicing\Packages\Adobe-Flash-For-Windows-onecoreuap-Package~31bf3856ad364e35~amd64~en-US~10.0.16299.15
' because it does not exist.
At line:11 char:3
+   Get-ChildItem -Path "$regkey"
+   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (HKEY_LOCAL_MACH...10.0.16299.15
:String) [Get-ChildItem], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand

April 4, 2018 at 2:05 pm

This isn't super obvious, but PS does support this. If you use

Get-ChildItem2

it actually uses an extended library to access lengthy paths. 🙂