首页 > 解决方案 > 变量 = 使用 try/catch 执行的脚本块

问题描述

我正在尝试查找特定注册表属性的存在,如果存在,则将变量设置为该值。我将执行 If/Then/ElseIf 序列,所以我不想将洞的东西包装在 Try/Catch 中以解决 PS5.1Get-ItemPropertyValue中不支持的事实-errorAction:silentlyContinue,所以我真的想设置值执行一个包含 try/catch 和一个空 catch 的代码块,像这样......

if ($value = @{try {Get-ItemPropertyValue "Registry::$nameKey" -name:AdskProductCode}catch{}}) {

我觉得这是可能的,我很接近,只是错过了一些细微差别。或者也许这是一个愚蠢的想法,有更好的方法吗?他们将 try/catch 保留在 if/then/else 中的关键原因是因为我将查找 AdskProductCode 而没有找到我将查找 AdskPackageCode 的属性,并且在每种情况下我对值的处理方式都不同。如果 try/catch 包装了 iff,那么找不到 AdskProductCode 会完全把我甩掉,如果寻找 AdskPackageCode,我永远不会去 else。如果没有至少有一个最终的 else,也许还有另一个 else if,所以简单地在 catch 中寻找 AdskPackageCode 是行不通的。我可以级联尝试/捕获的东西,但是天哪,这很丑。

标签: powershelltry-catchscriptblock

解决方案


解决 PS5.1 Get-ItemPropertyValue 不支持 -errorAction:silentlyContinue 的事实

实际上,从 PowerShell Core 7.0.0-preview.1 / Windows PowerShell v5.1 开始,Get-ItemPropertyValue意外地报告了语句终止而不是非终止错误 - 并且只有后一种错误可以使用 common
-ErrorAction参数
来控制。

这种有问题的行为 - 仅限于注册表(与包含相反)不存在的情况 - 已在此 GitHub 问题中报告。


/只能控制终止错误,并且使用空块作为终止错误相当于传递给产生非终止错误的 cmdlet。trycatchcatch-ErrorAction Ignore

正如Mathias R. Jessen指出的那样,您唯一的问题是您错误地将try/catch语句包装在@{ ... }- 一个哈希表文字中 - 这本身会导致语句终止错误。

您可能一直在考虑$( ... )子表达式运算符 ,它可以在这种情况下使用,但它的使用不是必需的,因此以下内容就足够了:

if ($value = try { Get-ItemPropertyValue "Registry::$nameKey" -name:AdskProductCode } catch{}) { ...

也就是说,您可以直接try/catch语句用作表达式,从而将其分配给变量。


鉴于Get-ItemPropertyValue' 的行为可能(并且希望会)最终得到修复,我建议采用不同的方法,但是:

改为使用Get-ItemProperty,并将结果对象上感兴趣的值名称作为属性访问:

if ($value = (Get-ItemProperty "Registry::$nameKey").AdskProductCode) { ...

笔记:

  • 一般假设是密钥路径"Registry::$nameKey"确实存在(即,可能不存在的只是注册表);要忽略不存在的关键路径,请使用-ErrorAction Ignore.
  • 以上假设没有严格模式或至多严格模式版本1有效。
  • 相反,如果Set-StrictMode -Version 2有效或更高,请不要使用直接属性访问和管道来Select-Object -ErrorAction Ignore -ExpandProperty AdskProductCode代替。

推荐阅读