Get file version in PowerShell

2020-01-26 16:03发布

How can you get the version information from a .dll or .exe file in PowerShell?

I am specifically interested in File Version, though other version information (that is, Company, Language, Product Name, etc.) would be helpful as well.

11条回答
再贱就再见
2楼-- · 2020-01-26 16:11

Just another way to do it is to use the built-in file access technique:

(get-item .\filename.exe).VersionInfo | FL

You can also get any particular property off the VersionInfo, thus:

(get-item .\filename.exe).VersionInfo.FileVersion

This is quite close to the dir technique.

查看更多
对你真心纯属浪费
3楼-- · 2020-01-26 16:12
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")
查看更多
Root(大扎)
4楼-- · 2020-01-26 16:17

Since PowerShell can call .NET classes, you could do the following:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo("somefilepath").FileVersion

Or as noted here on a list of files:

get-childitem * -include *.dll,*.exe | foreach-object { "{0}`t{1}" -f $_.Name, [System.Diagnostics.FileVersionInfo]::GetVersionInfo($_).FileVersion }

Or even nicer as a script: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/

查看更多
一纸荒年 Trace。
5楼-- · 2020-01-26 16:28

As EBGreen said, [System.Diagnostics.FileVersionInfo]::GetVersionInfo(path) will work, but remember that you can also get all the members of FileVersionInfo, for example:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo(path).CompanyName

You should be able to use every member of FileVersionInfo documented here, which will get you basically anything you could ever want about the file.

查看更多
我欲成王,谁敢阻挡
6楼-- · 2020-01-26 16:29

I realise this has already been answered, but if anyone's interested in typing fewer characters, I believe this is the shortest way of writing this in PS v3+:

ls application.exe | % versioninfo
  • ls is an alias for Get-ChildItem
  • % is an alias for ForEach-Object
  • versioninfo here is a shorthand way of writing {$_.VersionInfo}

The benefit of using ls in this way is that you can easily adapt it to look for a given file within subfolders. For example, the following command will return version info for all files called application.exe within subfolders:

ls application.exe -r | % versioninfo
  • -r is an alias for -Recurse

You can further refine this by adding -ea silentlycontinue to ignore things like permission errors in folders you can't search:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea is an alias for -ErrorAction

Finally, if you are getting ellipses (...) in your results, you can append | fl to return the information in a different format. This returns much more detail, although formatted in a list, rather that on one line per result:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl is an alias for Format-List

I realise this is very similar to xcud's reply in that ls and dir are both aliases for Get-ChildItem. But I'm hoping my "shortest" method will help someone.

The final example could be written in long-hand in the following way:

Get-ChildItem -Filter application.exe -Recurse -ErrorAction SilentlyContinue | ForEach-Object {$_.VersionInfo} | Format-List

... but I think my way is cooler and, for some, easier to remember. (But mostly cooler).

查看更多
劫难
7楼-- · 2020-01-26 16:31

Nowadays you can get the FileVersionInfo from Get-Item or Get-ChildItem, but it will show the original FileVersion from the shipped product, and not the updated version. For instance:

(Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.FileVersion

Interestingly, you can get the updated (patched) ProductVersion by using this:

(Get-Command C:\Windows\System32\Lsasrv.dll).Version

The distinction I'm making between "original" and "patched" is basically due to the way the FileVersion is calculated (see the docs here). Basically ever since Vista, the Windows API GetFileVersionInfo is querying part of the version information from the language neutral file (exe/dll) and the non-fixed part from a language-specific mui file (which isn't updated every time the files change).

So with a file like lsasrv (which got replaced due to security problems in SSL/TLS/RDS in November 2014) the versions reported by these two commands (at least for a while after that date) were different, and the second one is the more "correct" version.

However, although it's correct in LSASrv, it's possible for the ProductVersion and FileVersion to be different (it's common, in fact). So the only way to get the updated Fileversion straight from the assembly file is to build it up yourself from the parts, something like this:

Get-Item C:\Windows\System32\Lsasrv.dll | ft FileName, File*Part

Or by pulling the data from this:

[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName)

You can easily add this to all FileInfo objects by updating the TypeData in PowerShell:

Update-TypeData -TypeName System.IO.FileInfo -MemberName FileVersion -MemberType ScriptProperty -Value {
   [System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName) | % {
      [Version](($_.FileMajorPart, $_.FileMinorPart, $_.FileBuildPart, $_.FilePrivatePart)-join".") 
   }
}

Now every time you do Get-ChildItem or Get-Item you'll have a FileVersion property that shows the updated FileVersion ...

查看更多
登录 后发表回答