Thanks.

I was curious about this and ran a script to check all of the 
FileVersionInfo.ProductVersion properties from a few computers and found some 
interesting results from a number of programs.  It definitely seems like a lot 
of applications are not using the standard versioning scheme.  BTW, it appears 
that FileVersionInfo.FileVersion gave results in some cases where 
FileVersionInfo.ProductVersion either had no information, or used non period 
symbols, so at least from my very tiny sample, FileVersion may be more 
"reliable" over ProductVersion.

Here are some of the results of what I found that show the inconsistencies:


1.       FileVersionInfo.ProductVersion="7.0.0-20121019_01" from C:\Program 
Files (x86)\IBM\Tivoli\Remote Control\Controller\jre\bin\java.exe


2.       FileVersionInfo.ProductVersion= "e.x.p build-1280474" from C:\Program 
Files (x86)\Common Files\VMware\USB\vnetlib.exe (actual version is 9.0.0.28537)


3.       FileVersionInfo.ProductVersion="Release 0.63" from C:\Program Files 
(x86)\PuTTY\putty.exe (actual version is 0.63.0.0)


4.       FileVersionInfo.ProductVersion="7-9-5-5" from C:\Program Files 
(x86)\Siber Systems\AI RoboForm\robotaskbaricon.exe (actual version is 7.9.9.5)


5.       FileVersionInfo.ProductVersion= "5.21j.1926" from arc.exe (actual 
version is 5.21.10.1926)


6.       FileVersionInfo.ProductVersion= "3.05 (2010-04-27)" from upx.exe 
(actual version is 3.5.0.0)

For these programs, I checked the individual properties for FileMajorPart, 
FileMinorPart, FileBuildPart, FilePrivatePart and found that they offered the 
correct information in the cases above.  So it appears that if the program is 
known (as it was in James' case), directly typecasting the result of 
FileVersionInfo.ProductVersion to [Version] is sufficient, but if this may be 
needed across a random set of executables, that directly typecasting to 
[Version] may not work as expected and so the longer route may be needed in 
that case.

-Aakash Shah

From: [email protected] [mailto:[email protected]] On 
Behalf Of Michael B. Smith
Sent: Thursday, April 3, 2014 5:12 PM
To: [email protected]
Subject: RE: [NTSysADM] PowerShell tidy-up

Do be aware that you can defensively program for this eventuality. Even in 
script. :)

                $ver = (Get-Command 'C:\Program Files 
(x86)\AutoIt3\AutoIt3.exe').FileVersionInfo.Productversion
                $strVer = $ver.ToString()
                If( $strver.IndexOf( ',' ) -ge 0 )
                {
                                $strVer = $strVer.Replace( ',', '.' )
                                $ver = [Version] $ver
                }

And if you are using arbitrary input, you can use the static methods 
::TryParse() and ::Parse().

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Aakash Shah
Sent: Thursday, April 3, 2014 8:01 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

Good to know.  Thanks for the clarification!

-Aakash Shah

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Michael B. Smith
Sent: Thursday, April 3, 2014 3:43 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

If you have commas, then the author isn't using the standard macros (for C or 
C++) or the standard attribute (for CLR languages).

I can't speak as to why they are making their own lives more complicated.

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Aakash Shah
Sent: Thursday, April 3, 2014 6:36 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

Never mind - I misread James' original email.  He was replacing periods with an 
empty string.  Sorry about the confusion.

In this case, Michael's solution will work if the EXE is returning a result 
that contains periods.  However, it someone knows how to get around the comma 
problem, please let me know.

Thanks,

-Aakash Shah

From: Aakash Shah
Sent: Thursday, April 3, 2014 3:28 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

True, that works for many files and I was going to suggest that originally.  
However, I found that it doesn't seem to work when the results contain commas 
as James' appears to have (since in his original email, he replaced commas with 
periods).  Here is what I found when I used the [Version] typecast with a comma 
based result:

This will show us the results with commas:

PS C:\Users\aakash> (Get-Command 'C:\Program Files 
(x86)\AutoIt3\AutoIt3.exe').FileVersionInfo.Productversion
3, 3, 8, 1

However, if we attempt to typecast this, it errors out:

PS C:\Users\aakash> [version](Get-Command 'C:\Program Files 
(x86)\AutoIt3\AutoIt3.exe').FileVersionInfo.Productversion
Cannot convert value "3, 3, 8, 1" to type "System.Version". Error: "Version 
string portion was too short or too long."
At line:1 char:1
+ [version](Get-Command 'C:\Program Files 
(x86)\AutoIt3\AutoIt3.exe').FileVersionI ...
+ 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocation

This is why I extracted the individual components and joined them.

So the more direct method that you mentioned does work if the version number 
already contains periods, but does not appear to work when it contains commas.  
However, if I missed something though, please let me know since it would be 
nice if we can directly typecast the result of FileVersion.Productversion in 
all cases.

Thanks,

-Aakash Shah

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Michael B. Smith
Sent: Thursday, April 3, 2014 3:14 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

It's easier than that. :)

$FilePath = 'C:\Program Files\AppSense\Environment 
Manager\Agent\EMCoreService.exe'
$ver = [Version]( get-command $FilePath ).FileVersionInfo.ProductVersion
If ($ver -lt [Version]'8.4.495.0')
{
#do something
}

But a great idea...

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of Aakash Shah
Sent: Thursday, April 3, 2014 5:50 PM
To: [email protected]<mailto:[email protected]>
Subject: RE: [NTSysADM] PowerShell tidy-up

Another option to help address the problem with 11.2 and 1.13 is to type cast 
the version as a "[System.Version]" type.  You can use this to get the version 
number:

$FilePath = 'C:\Program Files\AppSense\Environment 
Manager\Agent\EMCoreService.exe'
$File = Get-Command $FilePath
$FileVersionInfo = @(
     $File.FileVersionInfo.FileMajorPart,
     $File.FileVersionInfo.FileMinorPart,
     $File.FileVersionInfo.FileBuildPart,
     $File.FileVersionInfo.FilePrivatePart
)

$FileVersion = [Version]($FileVersionInfo -join '.')

Now to compare this against another file, you can use:

If ($FileVersion -lt [Version]'8.4.495.0') { #do something }

-Aakash Shah

From: [email protected]<mailto:[email protected]> 
[mailto:[email protected]] On Behalf Of James Rankin
Sent: Thursday, April 3, 2014 1:20 PM
To: [email protected]<mailto:[email protected]>
Subject: Re: [NTSysADM] PowerShell tidy-up

Very good point. Luckily what I am dealing with here should all start as 8.4 
and have xxx.x as the last numbers, but I will pay a lot of attention to that 
in future, cheers!

On 3 April 2014 21:16, Ben Scott 
<[email protected]<mailto:[email protected]>> wrote:
On Thu, Apr 3, 2014 at 2:59 PM, James Rankin 
<[email protected]<mailto:[email protected]>> wrote:
> I did this quick bit of PS to check a file version number and then launch a
> patching process if it isn't at a certain level. It works OK but I am sure
> there is a much cleaner and more elegant way to do this. Any pointers?
  More of an observation than a suggestion:

  Testing version numbers is one of those things that you'd think
would be easy but ends up being ridiculously complicated.  Removing
separators and just treating it as one big number seems like a good
idea unless you want to compare version 11.2 with version 1.13.  Plus
some people throw in letters.  Testing release dates might seem like a
good alternative, but if the publisher is maintaining multiple release
branches, patch release 1.1.42 might be released after major release
2.0.0.  Blech.

  If the possible version numbers are more controlled, your method is
usually fine.

-- Ben



--
James Rankin
---------------------
RCL - Senior Technical Consultant (ACA, CCA, MCTS) | The Virtualization 
Practice Analyst - Desktop Virtualization
http://appsensebigot.blogspot.co.uk

Reply via email to