在PowerShell中获取文件版本


146

如何从PowerShell中的.dll.exe文件获取版本信息?

我特别感兴趣的File Version,但其他版本信息(也就是CompanyLanguageProduct Name,等)会以及帮助。

Answers:


140

由于PowerShell可以调用.NET类,因此您可以执行以下操作:

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

或如此处在文件列表中所述:

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

甚至更好地作为脚本:https : //jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/


8
有关不需要.NET对象的解决方案,请参见@Jaykul。恕我直言Jaykul的回答应该被选择为答案:)
Thomas Bratt

2
尽管其他答案给出的命令更短,但我尝试的所有命令都打印出了太多信息,并将文件路径截断为“ ...”。此答案中的第二个命令给出了您所需要的内容,适用于文件目录,并且以易于查看如何对其进行修改以返回其他信息的方式进行格式化。只需将命令中的.LegalCopyright更改为.FileVersion。
丹尼斯,

这是.NET EXE的正确版本。Jaykul的答案没有相同版本。
ashes999 2014年

这实际上是不对的。查看get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -force并将FilePrivatePart与FileVersion的最后一部分进行比较。FileVersion显示最初提供的内容,而不显示修补的版本。另一方面,此命令显示修补的版本号:(get-command C:\ Windows \ System32 \ ubpm.dll).Version
Jaykul 2014年

更好的示例是最近修补的C:\ Windows \ System32 \ Lsasrv.dll ...,但事实是(Get-Command ... ).Version返回ProductVersion而不是FileVersion,有时这很重要。因此,对于实际上返回更新的 FileVersion 的完整解决方案,请查看下面我的答案中的Update-TypeData示例。
Jaykul 2014年

170

现在,您可以从Get-Item或Get-ChildItem获取FileVersionInfo,但是它将显示出厂产品的原始FileVersion,而不是更新的版本。例如:

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

有趣的是,您可以使用以下命令获取更新的(已修补的)ProductVersion

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

我对“原始”和“修补”之间的区别基本上是由于FileVersion的计算方式(请参阅此处的文档)。基本上从Vista开始,Windows API GetFileVersionInfo会从语言中性文件(exe / dll)查询部分版本信息,并从特定于语言的mui文件中查询非固定部分(每次文件更改时不会更新) )。

因此,对于lsasrv之类的文件(由于SSL / TLS / RDS中的安全性问题而在2014年11月替换了该文件),这两个命令报告的版本(至少在该日期之后的一段时间内)有所不同,第二个命令是更多“正确”版本。

但是,尽管在LSASrv中是正确的,但ProductVersion和FileVersion可能会有所不同(实际上很常见)。因此,直接从装配文件中获取更新的 Fileversion 的唯一方法是从零件中自行构建它,如下所示:

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

或从中提取数据:

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

您可以通过在PowerShell中更新TypeData轻松将其添加到所有FileInfo对象:

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

现在每次你做一次Get-ChildItem或者Get-Item你将有一个FileVersion属性,它显示了更新的文件版本...


10
并使其等同于Lars接受的答案,请使用(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1 2011年

1
我对Get-Command应用于dll文件很感兴趣。您能详细说明一下它的作用吗?
Stephane Rolland 2014年

3
警告 FileVersionInfo.FileVersion是一个字符串表示形式,可能不是最新的。您应该查看FileVersionInfo.FileMajorPart,FileMinorPart,FileBuildPart,FilePrivatePart。请参阅GetFileVersionInfo()返回错误的文件的版本信息
bdeem

1
@Jaykul为了澄清我先前的评论/问题:原始答案演示了如何通过一些有趣的卷积在PowerShell中获取ProductVersion,因为ProductVersion可能比FileVersion更具指示性。原始答案没有提到VersionInfo.ProductVersion属性,可能是因为答案早于它。是否(Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersion有较新的更简单的方法来获得与答案中记录的相同的ProductVersion信息?我真的不相信Microsoft会一直使用该术语ProductVersion
Tydaeus

2
@Tydaeus这不是新的。您可以在文档上查找它,看看它有多远(.NET 1.1)😏。我的答案提到了ProductVersion,但是我们使用所有ScriptProperty代码计算的版本是真实的FILE版本,而不是ProductVersion。它们有时是相同的,但并非总是如此。😔不幸的是,每个真实的示例我都提出了Windows下一个服务版本中的更改😉docs.microsoft.com/ en
us/

50

“ dir”是Get-ChildItem的别名,当您从具有VersionInfo作为属性的文件系统中调用System.IO.FileInfo类时,它将返回该System.IO.FileInfo类。所以...

要获取单个文件的版本信息,请执行以下操作:

PS C:\Windows> (dir .\write.exe).VersionInfo | fl


OriginalFilename : write
FileDescription  : Windows Write
ProductName      : Microsoft® Windows® Operating System
Comments         :
CompanyName      : Microsoft Corporation
FileName         : C:\Windows\write.exe
FileVersion      : 6.1.7600.16385 (win7_rtm.090713-1255)
ProductVersion   : 6.1.7600.16385
IsDebug          : False
IsPatched        : False
IsPreRelease     : False
IsPrivateBuild   : False
IsSpecialBuild   : False
Language         : English (United States)
LegalCopyright   : © Microsoft Corporation. All rights reserved.
LegalTrademarks  :
PrivateBuild     :
SpecialBuild     :

对于多个文件,这是:

PS C:\Windows> dir *.exe | %{ $_.VersionInfo }

ProductVersion   FileVersion      FileName
--------------   -----------      --------
6.1.7600.16385   6.1.7600.1638... C:\Windows\bfsvc.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\explorer.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\fveupdate.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\HelpPane.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\hh.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\notepad.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\regedit.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\splwow64.exe
1,7,0,0          1,7,0,0          C:\Windows\twunk_16.exe
1,7,1,0          1,7,1,0          C:\Windows\twunk_32.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\winhlp32.exe
6.1.7600.16385   6.1.7600.1638... C:\Windows\write.exe

有用的是,您还包括其他常见的元数据(例如公司名称和说明)。
David Faivre

16

我更喜欢安装PowerShell社区扩展,仅使用它提供的Get-FileVersionInfo函数。

像这样:

Get-FileVersionInfo MyAssembly.dll

输出如下:

产品版本文件版本文件名
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C:\ Path \ To \ MyAssembly.dll

我已经在整个程序集目录中成功使用了它。


12

我知道已经解决了这个问题,但是如果有人想输入更少的字符,我相信这是在PS v3 +中编写此文字的最短方法:

ls application.exe | % versioninfo
  • ls 是的别名 Get-ChildItem
  • % 是的别名 ForEach-Object
  • versioninfo 这是一种速记方式 {$_.VersionInfo}

ls以这种方式使用的好处是,您可以轻松调整它以在子文件夹中查找给定的文件。例如,以下命令将返回application.exe在子文件夹中调用的所有文件的版本信息:

ls application.exe -r | % versioninfo
  • -r 是的别名 -Recurse

您可以通过添加-ea silentlycontinue忽略无法搜索的文件夹中的权限错误之类的内容来进一步完善此功能:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea 是的别名 -ErrorAction

最后,如果结果中出现省略号(...),则可以追加| fl以其他格式返回信息。尽管返回的格式是列表形式,但返回的结果更多得多,而不是每个结果一行:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl 是的别名 Format-List

我意识到这与xcud的回复非常相似,ls并且dir都是的别名Get-ChildItem。但我希望我的“最短”方法能对某人有所帮助。

最终的示例可以通过以下方式长时间编写:

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

...但是我认为我的方法更酷,而且在某些情况下更容易记住。(但大多凉爽)。


11

做到这一点的另一种方法是使用内置文件访问技术:

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

您还可以从VersionInfo获得任何特定的属性,因此:

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

这与dir技术非常接近。


(获取项目\\“ $ computerName” \“ C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe”)。VersionInfo.FileVersion为我工作。我需要从循环中添加计算机名称。
龙舌兰酒

7

这是基于其他答案的,但正是我所追求的:

(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion

我对Get-Command应用于dll文件很感兴趣。您能否详细说明其效果(甚至在调用属性FileVersionInfo之前)?
Stephane Rolland 2014年

dll文件包含的内容FileVersionInfo与exe文件一样。将此命令应用于路径将获得文件版本信息!
noelicus 2014年

4
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")

4

我发现这很有用:

function Get-Version($filePath)
{
   $name = @{Name="Name";Expression= {split-path -leaf $_.FileName}}
   $path = @{Name="Path";Expression= {split-path $_.FileName}}
   dir -recurse -path $filePath | % { if ($_.Name -match "(.*dll|.*exe)$") {$_.VersionInfo}} | select FileVersion, $name, $path
}

这是VBScript吗?
2016年

1
不,它的功能
强大

2

正如EBGreen所说,[System.Diagnostics.FileVersionInfo] :: GetVersionInfo(path)可以使用,但是请记住,您还可以获取FileVersionInfo的所有成员,例如:

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

您应该能够使用此处记录的FileVersionInfo的每个成员,这基本上可以为您提供有关该文件的任何所需信息。


1

这里是一种替代方法。它使用Get-WmiObject CIM_DATAFILE选择版本。

(Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version

使用名称中带有空格的共享路径,我得到“在此对象上找不到属性'Version'。请验证该属性是否存在。”
AnneTheAgile 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.