Holen Sie sich die Dateiversion in PowerShell

146

Wie können Sie die Versionsinformationen aus einer .dlloder einer .exeDatei in PowerShell abrufen?

Ich bin speziell interessiert ist File Version, obwohl andere Versionsinformationen (das heißt, Company, Language, Product Name, etc.) wären hilfreich , auch.

Kaiser XLII
quelle

Antworten:

140

Da PowerShell .NET- Klassen aufrufen kann , können Sie Folgendes tun:

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

Oder wie hier in einer Liste von Dateien angegeben:

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

Oder noch schöner als Skript: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/

Lars Truijens
quelle
8
Unter @Jaykul finden Sie eine Lösung, für die kein .NET-Objekt erforderlich ist. IMHO Jaykuls Antwort sollte als Antwort ausgewählt worden sein :)
Thomas Bratt
2
Obwohl die anderen Antworten kürzere Befehle enthalten, drucken alle, die ich versucht habe, zu viele Informationen aus und kürzen den Dateipfad auf "...". Der zweite Befehl in dieser Antwort enthält genau das, was Sie benötigen, funktioniert für ein Dateiverzeichnis und formatiert so, dass Sie leicht erkennen können, wie Sie es ändern können, um andere Informationen zurückzugeben. Ändern Sie einfach das .LegalCopyright im Befehl in .FileVersion.
Dennis
Dies ist die richtige Version für .NET EXEs. Jaykuls Antwort erhält nicht die gleiche Version.
Asche999
Das stimmt eigentlich nicht. Schauen Sie sich get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forcedas FilePrivatePart an und vergleichen Sie es mit dem letzten Teil der FileVersion. Die FileVersion zeigt, was ursprünglich ausgeliefert wurde, und nicht die gepatchte Version. Dieser Befehl zeigt andererseits die gepatchte Versionsnummer: (get-Befehl C: \ Windows \ System32 \ ubpm.dll)
.Version
Ein besseres Beispiel wäre das kürzlich gepatchte C: \ Windows \ System32 \ Lsasrv.dll ... aber die Wahrheit ist, dass (Get-Command ... ).Versiondie ProductVersion nicht die FileVersion zurückgibt , und manchmal ist das wichtig. Eine vollständige Lösung, die die aktualisierte FileVersion tatsächlich zurückgibt , finden Sie im Beispiel Update-TypeData in meiner Antwort unten.
Jaykul
170

Heutzutage können Sie FileVersionInfo von Get-Item oder Get-ChildItem herunterladen, es wird jedoch die ursprüngliche FileVersion des gelieferten Produkts und nicht die aktualisierte Version angezeigt. Zum Beispiel:

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

Interessanterweise können Sie die aktualisierte (gepatchte) ProductVersion folgendermaßen herunterladen :

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

Die Unterscheidung, die ich zwischen "Original" und "Patched" mache, beruht im Wesentlichen auf der Art und Weise, wie die FileVersion berechnet wird ( siehe die Dokumente hier ). Grundsätzlich fragt die Windows-API GetFileVersionInfo seit Vista einen Teil der Versionsinformationen aus der sprachneutralen Datei (exe / dll) und den nicht festen Teil aus einer sprachspezifischen Mui-Datei ab (die nicht jedes Mal aktualisiert wird, wenn sich die Dateien ändern ).

Bei einer Datei wie lsasrv (die aufgrund von Sicherheitsproblemen in SSL / TLS / RDS im November 2014 ersetzt wurde) waren die von diesen beiden Befehlen gemeldeten Versionen (zumindest für eine Weile nach diesem Datum) unterschiedlich, und die zweite ist die mehr "richtige" Version.

Obwohl dies in LSASrv korrekt ist, können ProductVersion und FileVersion unterschiedlich sein (dies ist tatsächlich üblich). Die einzige Möglichkeit, die aktualisierte Dateiversion direkt aus der Baugruppendatei zu erhalten, besteht darin, sie selbst aus den Teilen zusammenzustellen.

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

Oder indem Sie die Daten daraus ziehen:

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

Sie können dies einfach zu allen FileInfo-Objekten hinzufügen, indem Sie die TypeData in PowerShell aktualisieren:

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

Nun jedes Mal , wenn Sie tun , Get-ChildItemoder Get-ItemSie eine haben FileVersionEigenschaft , dass zeigt die aktualisierte Fileversion ...

Jaykul
quelle
10
Und um dies zum Äquivalent von Lars 'akzeptierter Antwort zu machen, benutze einfach(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1
1
Ich bin fasziniert von der Get-Commandauf eine DLL angewendeten Datei. Könnten Sie die Wirkung näher erläutern?
Stephane Rolland
3
Warnung Die FileVersionInfo.FileVersion ist eine Zeichenfolgendarstellung, die möglicherweise nicht aktuell ist. Sie sollten sich FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart ansehen. Siehe GetFileVersionInfo () gibt die Versionsinformationen der falschen Datei zurück
bdeem
1
@Jaykul Um meinen früheren Kommentar / meine frühere Frage zu verdeutlichen: Die ursprüngliche Antwort zeigt, wie Sie die ProductVersion in PowerShell durch einige interessante Faltungen erhalten, da ProductVersion möglicherweise aussagekräftiger ist als FileVersion. In der ursprünglichen Antwort wird die Eigenschaft VersionInfo.ProductVersion nicht erwähnt, möglicherweise weil die Antwort vor der Antwort liegt. Ist (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersioneine neuere einfachere Möglichkeit, dieselben ProductVersion-Informationen zu erhalten, die in der Antwort dokumentiert sind? Ich vertraue nicht wirklich darauf, dass Microsoft den Begriff ProductVersionkonsequent verwendet.
Tydaeus
2
@Tydaeus Es ist nicht neu. Sie können es in Dokumenten nachschlagen und sehen, wie weit es zurückreicht (.NET 1.1) 😏. In meiner Antwort wird ProductVersion erwähnt, aber die Version, die wir mit dem gesamten ScriptProperty-Code berechnen, ist die echte FILE-Version, nicht die ProductVersion. Sie sind manchmal gleich, aber nicht immer. 😔 Und leider habe ich in jedem realen Beispiel Änderungen in der nächsten Service-Version von Windows vorgenommen. S. docs.microsoft.com/en-us/dotnet/api/…
Jaykul
50

'dir' ist ein Alias ​​für Get-ChildItem, der eine System.IO.FileInfo-Klasse zurückgibt, wenn Sie sie aus dem Dateisystem aufrufen, dessen Version VersionInfo ist. So ...

Gehen Sie folgendermaßen vor, um die Versionsinformationen einer einzelnen Datei abzurufen:

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     :

Für mehrere Dateien gilt Folgendes:

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
quelle
Hilfreich, da Sie auch andere gängige Metadaten (wie Firmenname und Beschreibung) angeben.
David Faivre
16

Ich bevorzuge die Installation der PowerShell Community Extensions und verwende einfach die darin enthaltene Funktion Get-FileVersionInfo.

Wie so:

Get-FileVersionInfo MyAssembly.dll

mit Ausgabe wie:

ProductVersion FileVersion FileName
-------------- ----------- --------
1.0.2907.18095 1.0.2907.18095 C: \ Path \ To \ MyAssembly.dll

Ich habe es mit großem Erfolg gegen ein ganzes Verzeichnis von Baugruppen verwendet.

David Mohundro
quelle
12

Mir ist klar, dass dies bereits beantwortet wurde, aber wenn jemand daran interessiert ist, weniger Zeichen einzugeben, ist dies meiner Meinung nach die kürzeste Art, dies in PS v3 + zu schreiben:

ls application.exe | % versioninfo
  • ls ist ein Alias ​​für Get-ChildItem
  • % ist ein Alias ​​für ForEach-Object
  • versioninfo Hier ist eine Kurzschrift {$_.VersionInfo}

Der Vorteil lsdieser Verwendung besteht darin, dass Sie sie einfach anpassen können, um in Unterordnern nach einer bestimmten Datei zu suchen. Der folgende Befehl gibt beispielsweise Versionsinformationen für alle Dateien zurück, die application.exein Unterordnern aufgerufen werden:

ls application.exe -r | % versioninfo
  • -r ist ein Alias ​​für -Recurse

Sie können dies weiter verfeinern, indem Sie -ea silentlycontinueDinge wie Berechtigungsfehler in Ordnern ignorieren, die Sie nicht durchsuchen können:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea ist ein Alias ​​für -ErrorAction

Wenn Ihre Ergebnisse Ellipsen (...) enthalten, können Sie | fldie Informationen in einem anderen Format zurückgeben. Dies gibt viel mehr Details zurück, obwohl in einer Liste formatiert, anstatt in einer Zeile pro Ergebnis:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl ist ein Alias ​​für Format-List

Mir ist klar, dass dies der Antwort von xcud sehr ähnlich ist lsund dirbeide Aliase für sind Get-ChildItem. Aber ich hoffe, dass meine "kürzeste" Methode jemandem hilft.

Das letzte Beispiel könnte folgendermaßen in Langschrift geschrieben werden:

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

... aber ich denke, mein Weg ist cooler und für manche leichter zu merken. (Aber meistens cooler).

Oliver-Clare
quelle
11

Eine andere Möglichkeit besteht darin, die integrierte Dateizugriffstechnik zu verwenden:

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

Sie können auch eine bestimmte Eigenschaft aus der VersionInfo abrufen, also:

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

Dies kommt der Dir-Technik ziemlich nahe.

Wir s
quelle
(get-item \\ "$ computerName" \ "C $ \ Programme \ Symantec AntiVirus \ VPDN_LU.exe"). VersionInfo.FileVersion hat bei mir funktioniert. Ich musste einen Computernamen aus einer Schleife hinzufügen.
Tequila
7

Dies basiert auf den anderen Antworten, ist aber genau das, wonach ich gesucht habe:

(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
Noelicus
quelle
Ich bin fasziniert von der Get-Commandauf eine DLL angewendeten Datei. Könnten Sie die Auswirkungen näher erläutern (bevor Sie die Eigenschaft FileVersionInfo aufrufen)?
Stephane Rolland
DLL-Dateien enthalten FileVersionInfogenau wie exe-Dateien. Wenn Sie diesen Befehl auf den Pfad anwenden, erhalten Sie die Informationen zur Dateiversion!
Noelicus
4
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")
EBGreen
quelle
4

Ich finde das nützlich:

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
quelle
Ist das ein VBScript?
Macetw
1
Nein, es ist Powershell
Chriseyre2000
2

Wie EBGreen sagte, funktioniert [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (Pfad), aber denken Sie daran, dass Sie auch alle Mitglieder von FileVersionInfo abrufen können, zum Beispiel:

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

Sie sollten in der Lage sein, jedes hier dokumentierte Mitglied von FileVersionInfo zu verwenden, wodurch Sie im Grunde alles erhalten, was Sie jemals von der Datei erwarten könnten.

Adam Haile
quelle
1

Hier eine alternative Methode. Es verwendet Get-WmiObject CIM_DATAFILE, um die Version auszuwählen.

(Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version
Knöchel-Dragger
quelle
Bei Verwendung eines Freigabepfads mit Leerzeichen im Namen wurde "Die Eigenschaft 'Version' wurde für dieses Objekt nicht gefunden. Stellen Sie sicher, dass die Eigenschaft vorhanden ist."
AnneTheAgile