PowerShell: 引用带有空格的属性

huangapple go评论65阅读模式
英文:

PowerShell: Referencing a property with spaces

问题

我正在尝试创建一个脚本,用于检查注册表键/值。如果值是特定版本,将输出。如果值不是该版本,然后创建一个新值。我遇到的问题是属性分为两个单词。

键是 hklm:software\dg

值名称是 "Agent version"

值数据是 7.8.5.005

我尝试过下面的脚本,但我不太熟悉如何正确检查 "Agent version" 值的版本,因为它分为两个单词。该脚本总是创建新的测试值。我尝试过双引号、单引号、大括号包围 "Agent version"。似乎什么都不起作用。如果有更简单的方法来做这个,我愿意听取建议。提前感谢!

$val = Get-ItemProperty -Path hklm:software\dg

if($val.'Agent version' -eq '7.8.5.005') {
    Write-Host "Agent is current" -ForegroundColor Green
}
else {
    New-ItemProperty -Path hklm:software\dg -Name "Test" -Value 0
}
英文:

I am trying to create a script that will check a registry key/value. If the value is a certain version, write an output. If the value is not that version, then create a new value. The problem I am coming across is the property is split into two words.

The key is hklm:software\dg

The value name is "Agent version"

The value data is 7.8.5.005

I have tried the script below but I'm just not familiar with how to properly check the version of the value "Agent version" since it is split into two words. The script always creates the new test value. I have tried double quotes, single quotes, curly brackets around agent version. Nothing seems to work. If there is an easier way to do this, I am all ears. Thanks in advance!

$val = Get-ItemProperty -Path hklm:software\dg

if($val.'agent version' -eq 7.8.5.005) {
Write-Host Agent is current -ForegroundColor Green
}
else {
New-ItemProperty -Path hklm:software\dg -Name "Test" -value 0
}

答案1

得分: 2

<!-- language-all: sh -->

在问题的出色评论基础上继续构建:

**tl;dr**

将 `$val.&#39;agent version&#39; -eq 7.8.5.005` 替换为:

注意 [version] 强制转换和 RHS 操作数周围的 '...'。

由于 LHS 使用了 [version],在 '7.8.5.5' 之前它也是不必要的

[version] $val.'agent version' -eq '7.8.5.5' # 注意:0 填充不相关


一般来说,要构造字面上的 `[version]` 实例,你必须从一个 _字符串_ 进行强制转换:

[version] '7.8.5.5' # '...' 是必需的


---


针对你的帖子标题隐含的 _一般_ 问题:

* **将包含 *特殊字符*,比如 *空格* 的(字面上的)属性名用 `&#39;...&#39;` 包围确实是正确的解决方法**(在属性名 _本身_ 包含 `&#39;` 实例的极少数情况下,_双重_ 使用它们(`&#39;&#39;`))。

  * 至于 PowerShell 认为属性名(标识符)中哪些字符是 *特殊字符*,请参见 [此答案](https://stackoverflow.com/a/65268127/45375)。

---

至于 **你尝试过的**:

* **Windows 注册表 *没有* 直接表示 _版本号_ 的数据类型** - 用一个 _字符串_ 值 (`REG_SZ`) 来表示版本号,并且通过 [`Get-ItemProperty`](https://learn.microsoft.com/powershell/module/microsoft.powershell.management/get-itemproperty) 或者 - 直接检索注册表 _值_ - 通过 [`Get-ItemPropertyValue`](https://learn.microsoft.com/powershell/module/microsoft.powershell.management/get-itempropertyvalue) 将其转换为 .NET `[string]` 实例。

* **同样地,PowerShell 也没有用于版本号的字面表示法**,但是 **你可以将 _字符串_ 强制转换为 `[version]`** 以构造 [`System.Version`](https://learn.microsoft.com/en-US/dotnet/api/System.Version) 实例。

  * 正如 [zett42](https://stackoverflow.com/users/7571258/zett42) 指出的,未加引号的 `7.8.5.005` 字面上的值实际上会被解析为 `$null`,因为它被解析为 `[double]` 实例 `7.8`,你试图在其中访问 (隐式字符串化的) `[double]` 实例 `5.005` _作为属性_,显然这个属性并不存在。

  * 你可以通过将这些表达式括在 [脚本块](https://learn.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_Script_Blocks) (`{ ... }`) 中,然后深入探讨该脚本块的 [`.Ast` 属性](https://learn.microsoft.com/en-US/dotnet/api/System.Management.Automation.Language.ScriptBlockAst) 来深入了解 PowerShell 是如何解析这些表达式的 - 请注意 `5.005` 被列为 `Member` 访问:

        PS&gt; { 7.8.5.005 }.Ast.EndBlock.Statements.PipelineElements.Expression

        Expression      : 7.8
        Member          : 5.005
        Static          : False
        NullConditional : False
        StaticType      : System.Object
        Extent          : 7.8.5.005
        Parent          : 7.8.5.005

**只有 `[version]` 实例有 _有意义的版本号比较_**。

由于在比较操作的 _左操作数_ (如 `-eq` 中) 使用类型 `[version]` 就足以比较版本号,你可以采取捷径,使用 _字符串字面值_ 作为 RHS,就像顶部所示。
英文:

<!-- language-all: sh -->

Building on the great comments on the question:

tl;dr

Replace $val.&#39;agent version&#39; -eq 7.8.5.005 with:

# Note the [version] cast, and the &#39;...&#39; around the RHS operand.
# Because the LHS uses [version], it isn&#39;t also needed before &#39;7.8.5.5&#39;
[version] $val.&#39;agent version&#39; -eq &#39;7.8.5.5&#39;  # Note: 0-padding is irrelevant

In general, to construct a literal [version] instance, you must cast from a string:

[version] &#39;7.8.5.5&#39; # &#39;...&#39; required

To address the general question implied by your post's title:

  • Enclosing a (literal) property name containing special characters such as spaces in &#39;...&#39; is indeed the right solution (in the unlikely event that the name itself contains &#39; instances, double them (&#39;&#39;)).

    • As for which characters PowerShell considers special in a property name (identifier), see this answer.

As for what you tried:

  • The Windows registry has no data type that directly represents a version number - a string value (REG_SZ) is used to represent version numbers, and that translates into a .NET [string] instance via Get-ItemProperty or - to retrieve a registry value directly - via Get-ItemPropertyValue.

  • Similarly, PowerShell also has no literal notation for version numbers, but you can cast a string to [version] in order to construct a System.Version instance.

    • As zett42 notes, the unquoted 7.8.5.005 literal effectively evaluates to $null, because it is parsed as [double] instance 7.8 on which you're trying to access the (implicitly stringified) [double] instance 5.005 as a property, which obviously doesn't exist.

    • You can gain insights into how PowerShell parses such expressions by enclosing them in a script block ({ ... }), and drilling down into that script block's .Ast property - note how 5.005 is listed as a Member access:

      PS&gt; { 7.8.5.005 }.Ast.EndBlock.Statements.PipelineElements.Expression
      
      Expression      : 7.8
      Member          : 5.005
      Static          : False
      NullConditional : False
      StaticType      : System.Object
      Extent          : 7.8.5.005
      Parent          : 7.8.5.005
      

Only [version] instances compare meaningfully as version numbers.

Since it is sufficient for the LHS of a comparison operation, such as with -eq, to be of type [version] in order to compare version numbers, you can take a shortcut and use a string literal as the RHS, as shown at the top.

huangapple
  • 本文由 发表于 2023年2月24日 04:06:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75549815.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定