Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Powershell compare between string and double?

Tags:

powershell

I just realized that PowerShell can compare between string and number, I don't understand this because they are different types. How can PowerShell compare them?

PS C:\> Get-Host | Select-Object Version

Version
-------
5.1.19041.1023


PS C:\> $version = (Get-WmiObject -Class Win32_Product | where name -eq 'AWS Command Line Interface v2').Version
PS C:\> $version
2.0.7.0
PS C:\> $version -is [string]
True
PS C:\> 2.0 -is [double]
True
PS C:\> $version -gt 2.0
True
PS C:\> $version -gt 2.1
False
PS C:\> $version -gt 2.0.9
True
like image 209
Tuan Nguyen Avatar asked Apr 18 '26 04:04

Tuan Nguyen


1 Answers

... and you probably don't want to use either of these types,
but use the [Version] class type instead:

$version = [Version]'2.0.7.0'
$version -gt [Version]'2.0'
True
$version -gt [Version]'2.1'
False
$version -gt [Version]'2.0.9'
False

For what you tried:

As you noted yourself, the version property of the WMI query returns a [String] type and numbers with a (single) dot automatically cast to a [Double]. Knowing that the type at the LHS (left hand side) of the operator dictates the comparison type, all the concerned comparison examples in the question are string comparisons. Meaning:

'2.0.7.0' -gt '2.0'
True
'2.0.7.0' -gt '2.1'
False

The unexpected thing though, is that an (unquoted) number with 2 or more dots returns a $Null:

$Null -eq 2.0.9
True

Which will be cased to an empty string in the following comparison:

'2.0.7.0' -gt 2.0.9 # --> '2.0.7.0' -gt $Null --> '2.0.7.0' -gt ''
True

I have created a new PowerShell request for this issue:
#15756 Unquoted numbers with two or more dots should cast to a [version] rather then $Null


Addendum
The explanation why a number with 2 or more dots doesn't generate an (syntax) error is covered in the response of the related #15756 request.

In fact only the first dot is a interpreted as a decimal separator, the rest of the dots are presumed member (property/method) separators.
By default, PowerShell is not a strict language. This implies that if you references to non-existent properties of any object type (including strings and even primitives), it just returns $Null.

Huh???, I can understand that a primitive has methods like 2.0.ToInt32($Null) but how could a primitive as a double have a (custom) property as e.g. 9?
In PowerShell, it is possible to "decorate" (add a property to) any object using the Add-Member cmdlet:

$Version = 2.0 |Add-Member 9 'Nine' -PassThru
$Version |ConvertTo-Json
{
  "value": 2.0,
  "9": "Nine"
}
$Version -is [Double]
True
$Version.9
Nine

To force an error if you reference a non-existent property, you might use the Set-StrictMode cmdlet:

Set-StrictMode -Version Latest
2.0.9 # Similar to e.g.: $Version.0

PropertyNotFoundException: The property '9' cannot be found on this object. Verify that the property exists.

like image 135
iRon Avatar answered Apr 21 '26 08:04

iRon