2

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
}
  • 4
    try with `if([version] $val.'agent version' -eq [version] '7.8.5.005') {....` – Santiago Squarzon Feb 23 '23 at 20:08
  • 3
    When you write `7.8.5.005` without quotes in an _expression_, PowerShell creates a decimal number `7.8` and then looks for a property named `5.005` within that number object. Property doesn't exist, so it resolves to `$null`. So you are actually comparing a string to `$null`, which always resolves to `$false`. Unless the property `agent version` doesn't exist, then the expression would actually resolve to `$true`! – zett42 Feb 23 '23 at 22:24
  • Thank you! I just needed to add '...' around the version number, so this ended up working for me: $val.'Agent version' -eq '7.8.5.005' – mannyfresh86 Feb 24 '23 at 13:00

1 Answers1

2

Building on the great comments on the question:

tl;dr

Replace $val.'agent version' -eq 7.8.5.005 with:

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

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

[version] '7.8.5.5' # '...' required

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

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

    • 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> { 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.

mklement0
  • 382,024
  • 64
  • 607
  • 775