I am trying to look for the presence of a specific registry property and if present set a variable to the value. I will be doing an If/Then/ElseIf sequence, so I don't want to wrap the hole thing in a Try/Catch to address the fact that in PS5.1 Get-ItemPropertyValue
doesn't support -errorAction:silentlyContinue
, so I really want to set the value to the execution of a code block that includes the try/catch with an empty catch, something like this...
if ($value = @{try {Get-ItemPropertyValue "Registry::$nameKey" -name:AdskProductCode}catch{}}) {
I feel like it's possible and I am close and just missing some nuance. Or perhaps this is a stupid idea and there is a better approach? They key reason for keeping the try/catch inside the if/then/else is because I will look for AdskProductCode and not finding that property I will look for AdskPackageCode, and in each case what I do with the value is different. If the try/catch wraps the iff then not finding AdskProductCode dumps me out completely and I never get to the else if looking for AdskPackageCode. Failing that there will be at least a final else, and maybe another else if, so simply looking for AdskPackageCode in the catch doesn't work. I could cascade the try/catch stuff, but good lord that's ugly.
to address the fact that in PS5.1 Get-ItemPropertyValue doesn't support -errorAction:silentlyContinue
Indeed, as of PowerShell Core 7.0.0-preview.1 / Windows PowerShell v5.1, Get-ItemPropertyValue
unexpectedly reports a statement-terminating rather than a non-terminating error - and only the latter kind of error can be controlled with the common -ErrorAction
parameter.
This problematic behavior - restricted to the case where the registry value (as opposed to the containing key) doesn't exist - has been reported in this GitHub issue.
It is only terminating errors that try
/ catch
can control, and using an empty catch
block for a terminating error is the equivalent of passing -ErrorAction Ignore
to a cmdlet producing a non-terminating error.
Your only problem, as Mathias R. Jessen points out, was that you mistakenly wrapped your try
/ catch
statement in @{ ... }
- a hashtable literal - which itself caused a statement-terminating error.
You may have been thinking of $( ... )
, the subexpression operator, which would work in this case, but its use isn't necessary, so the following is enough:
if ($value = try { Get-ItemPropertyValue "Registry::$nameKey" -name:AdskProductCode } catch{}) { ...
That is, you can directly use a try
/ catch
statement as an expression and therefore assign it to a variable.
Given that Get-ItemPropertyValue
's behavior may - and hopefully will - eventually be fixed, I suggest a different approach, however:
Use Get-ItemProperty
instead, and access the value name of interest on the resulting object as a property:
if ($value = (Get-ItemProperty "Registry::$nameKey").AdskProductCode) { ...
Note:
"Registry::$nameKey"
does exist (i.e., that it is only the registry value that may not exist); to ignore the non-existence of the key path too, use -ErrorAction Ignore
.1
is in effect.Set-StrictMode -Version 2
or higher is in effect, don't use direct property access and pipe to Select-Object -ErrorAction Ignore -ExpandProperty AdskProductCode
instead.