MSEndpointMgr / IntuneAppFactory

Intune App Factory automates Win32 application packaging in Intune.
https://msendpointmgr.com/intune-app-factory
MIT License
32 stars 12 forks source link

Comparison of versions fails when found app source version is not a valid version variable (Test-AppList.ps1) #14

Open PZan opened 9 months ago

PZan commented 9 months ago

The Evergreen package for AdoptiumTemurin17 (+other OpenJDK and probably other apps as well) has an unconventional version value, i.e. "17.0.9+9".

When Test-AppList.ps1 attempts to compare this with the Intune Package the try-catch-statement will fail due to it trying to compare version ([version]) variables and 17.0.9+9 is not parseable.

I worked around this by some small modifications to convert the version returned by Evergreen to a parseable value (line 291-ish).

# Convert $AppItem.Version to parsable value
$VersionSplit = $AppItem.Version.Split(".") | ForEach-Object {($_ -replace '\W','.')}
$AppItemVersionString = $VersionSplit -join "."
Write-Output -InputObject "Converted [$($AppItem.Version)] to [$AppItemVersionString] (likely same value)"

And instead of comparing $AppItem.Version compare $AppItemVersionString (line 294)

if ([System.Version]::Parse($AppItemVersionString) -gt [System.Version]$Win32AppLatestPublishedVersion) {

This converted variable should also replace the $AppItem.Version as the value for AppSetupVersion in to the $AppListItem PSCustomObject (line 324).

This string conversion might not be complete, since I only worked with my particular case with Temurin, but I'm thinking a possible solution could be to determine if the string is parseable on beforehand, and opt for string comparison in case it is not. This following function could assist when deciding if string or version variables should be compared:

function isVersion {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [string]
        $String 
    )

    try {
        $null = [version]::Parse($String)
        [bool]$isVersion = $true
        Write-Verbose -Message "Successfully parsed string value [$String] to version."
    }
    catch [System.Exception] {
        [bool]$isVersion = $false
        Write-Warning -Message "String value [$String] not parseable as version"
    }
    return $isVersion
}
NickolajA commented 2 weeks ago

This sounds like a fantastic idea. I'll incorporate this functionality in 1.1.0 later tonight, thanks for sharing!

Wouldn't it just be so much more easier if everyone would follow standards? 😆

NickolajA commented 2 weeks ago

I'm thinking that taking your method, but just to do kind of the opposite where I split on each non-numerical character that's then joined together to a semantic versioning string (in the example of yours above):

$Version = "17.0.9+9"
$ParsedVersion = ($Version -split "\D") -join "."

That should take care of most scenarios where a version string contains 'invalid' characters. I'll embed your method to see if the detected version string can be parsed successfully, and if it can't the next step would be to attempt to convert the version string into a valid value that's usually by the pipeline.

PZan commented 1 week ago

That will probably work. I can't recall the details, but in a similar, self made, solution for ConfigMgr I actually opted against that, or had customizations per app as we discovered some applications where it would result in a fifth block (ie 1.2.3.4.5). I think it was Oracle JRE which had an even crazier version string than Temurin, something stupid like of 1.8.5b.+10.