Получить версию файла в PowerShell

146

Как вы можете получить информацию о версии от .dllили.exe в PowerShell?

Я специально заинтересованы в File Version, хотя другая информация о версии (то есть Company, Language, Product Nameи т.д.) было бы полезно , как хорошо.

Император XLII
источник

Ответы:

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
Посмотрите @Jaykul для решения, которое не требует объекта .NET. ИМХО Ответ Джейкула должен был быть выбран в качестве ответа :)
Томас Братт
2
Хотя другие ответы дают более короткие команды, все те, которые я пробовал, выводят слишком много информации и усекают путь к файлу до «...». Вторая команда в этом ответе дает именно то, что вам нужно, работает для каталога файлов и выполняет форматирование таким образом, чтобы было легко увидеть, как его изменить, чтобы получить другую информацию. Просто измените .LegalCopyright в команде на .FileVersion.
Деннис
Это правильная версия для .NET EXE. Jaykul ответ не получает ту же версию.
ashes999
Это на самом деле не правильно. Посмотрите get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forceи сравните FilePrivatePart с последней частью FileVersion. FileVersion показывает, что было отправлено, а не исправленную версию. Эта команда, с другой стороны, показывает исправленный номер версии: (get-команда C: \ Windows \ System32 \ ubpm.dll). Версия
Jaykul
Лучшим примером был бы недавно исправленный C: \ Windows \ System32 \ Lsasrv.dll ... но правда в том, что (Get-Command ... ).Versionвозвращает ProductVersion, а не FileVersion , а иногда это имеет значение. Так что для полного решения, которое фактически возвращает обновленный FileVersion, посмотрите пример Update-TypeData в моем ответе ниже.
Джайкуль
170

В настоящее время вы можете получить FileVersionInfo из Get-Item или Get-ChildItem, но он будет показывать оригинальный 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 года) версии этих двух команд (по крайней мере, некоторое время после этой даты) были разными, и вторая - более «правильная» версия.

Однако, хотя это правильно в LSASrv, возможно, что ProductVersion и FileVersion могут быть разными (на самом деле это обычное дело). Так что единственный способ получить обновленный Fileversion прямо из файла сборки - это создать его самостоятельно из частей, примерно так:

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

Или потянув данные из этого:

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

Вы можете легко добавить это ко всем объектам FileInfo, обновив TypeData в PowerShell:

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свойство, которое показывает обновленный FileVersion ...

Jaykul
источник
10
И чтобы сделать это эквивалентом принятого ответа Ларса, просто используйте(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1
1
Я заинтригован о Get-Commandприменении к файлу DLL. Не могли бы вы подробнее рассказать о его эффекте?
Стефан Роллан
3
Предупреждение FileVersionInfo.FileVersion - это строковое представление, которое может быть устаревшим. Вы должны посмотреть на FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart. См. GetFileVersionInfo () возвращает неверную информацию о версии файла
bdeem
1
@Jaykul Чтобы прояснить мой предыдущий комментарий / вопрос: оригинальный ответ демонстрирует, как получить ProductVersion в PowerShell через некоторые интересные свертки, потому что ProductVersion может быть более показательным, чем FileVersion. В первоначальном ответе не упоминается свойство VersionInfo.ProductVersion, возможно, потому, что ответ предшествует ему. Является (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersionли более простой способ получить ту же информацию о ProductVersion, которая описана в ответе? Я действительно не доверяю Microsoft использовать этот термин ProductVersionпоследовательно.
Тидей
2
@Tydaeus Это не ново. Вы можете посмотреть его в документации и посмотреть, как далеко он уходит (.NET 1.1) 😏. В моем ответе упоминается ProductVersion, но версия, которую мы рассчитываем со всем этим кодом ScriptProperty, является реальной версией FILE, а не ProductVersion. Они иногда одинаковы, но не всегда. 😔 И, к сожалению, каждый реальный пример, с которым я сталкиваюсь, вносит изменения в следующий сервисный выпуск Windows 😉 docs.microsoft.com/en-us/dotnet/api/…
Jaykul
50

'dir' - это псевдоним для Get-ChildItem, который будет возвращать класс System.IO.FileInfo при вызове его из файловой системы, в которой свойство VersionInfo является свойством. Так ...

Чтобы получить информацию о версии одного файла, сделайте это:

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
xcud
источник
Полезно в том, что вы включаете и другие распространенные метаданные (например, название компании и описание).
Дэвид Фэйвр
16

Я предпочитаю устанавливать расширения сообщества PowerShell и просто использовать предоставляемую им функцию Get-FileVersionInfo.

Вот так:

Get-FileVersionInfo MyAssembly.dll

с выводом как:

ProductVersion FileVersion FileName
-------------- ----------- --------
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

... но я думаю, что мой путь круче и для некоторых легче запомнить. (Но в основном круче).

оливер-Clare
источник
11

Еще один способ сделать это - использовать встроенную технику доступа к файлам:

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

Вы также можете получить любое конкретное свойство из VersionInfo, таким образом:

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

Это довольно близко к технике DIR.

Wes
источник
(get-item \\ "$ computerName" \ "C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe"). VersionInfo.FileVersion работал для меня. Мне нужно было добавить имя компьютера из цикла.
Текила
7

Это основано на других ответах, но это именно то, что я был после:

(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
noelicus
источник
Я заинтригован о Get-Commandприменении к файлу DLL. Не могли бы вы подробнее рассказать о его эффекте (еще до вызова свойства FileVersionInfo)?
Стефан Роллан
DLL-файлы содержат так FileVersionInfoже, как исполняемые файлы. Применяя эту команду к пути, вы получите информацию о версии файла!
noelicus 22.10.14
4
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")
EBGreen
источник
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
}
Chriseyre2000
источник
Это VBScript?
macetw
1
Нет, это
PowerShell
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
Knuckle-Dragger
источник
используя общий ресурс с пробелами в имени, я получил «Свойство« Версия »не может быть найдено для этого объекта. Убедитесь, что свойство существует».
AnneTheAgile