How can I force conversion to type System.Version
in PowerShell, or more likely, better understand why I cannot arbitrarily assign number strings type System.Version
?
We ingest some software updates in folders whose titles include version numbers. In trying to get reports on what the latest versions ingested are, I have been doing the following quick and dirty:
ForEach ($Folder in $(Get-ChildItem -Path $SoftwareDirectory -Directory))
{
$CurrentVersion = $Folder -Replace "[^0-9.]"
If ($CurrentVersion -ne $null)
{
If ([System.Version]$CurrentVersion -gt [System.Version]$MaxVersion)
{
$MaxVersion = $CurrentVersion
$MaxFolder = $Folder
}
}
}
This would be fed directory titles like the following,
- foo-tools-1.12.file
- bar-static-3.4.0.file
Most of the time, this is acceptable. However, when encountering some oddballs with longer numbers, like the following,
- applet-4u331r364.file
In which case, System.Version
refuses the resulting string as being too long.
Cannot convert value "4331364" to type "System.Version". Error: "Version string portion was too short or too long."
CodePudding user response:
You need to ensure that your version strings have at least two components in order for a cast to [version]
to succeed:
(
@(
'oo-tools-1.12.file'
'bar-static-3.4.0.file'
'applet-4u331r364.file'
) -replace '[^0-9.]'
).TrimEnd('.') -replace '^[^.] $', '$&.0' | ForEach-Object { [version] $_ }
The above transforms 'applet-4u331r364.file'
into '4331364.0'
, which works when cast to [version]
.
Note that you can avoid the need for .TrimEnd('.')
if you exclude the filename extension to begin with: $Folder.BaseName -replace '[^0-9.]'
-replace '^[^.] $', '$&.0'
matches only strings that contain no .
chars., in full, i.e. only those that don't already have at least two components; replacement expression $&.0
appends literal .0
to the matched string ($&
).
Output (via Format-Table -AutoSize
):
Major Minor Build Revision
----- ----- ----- --------
1 12 -1 -1
3 4 0 -1
4331364 0 -1 -1