Obtenir la version du fichier dans PowerShell

146

Comment pouvez-vous obtenir les informations de version d'un fichier .dllou .exedans PowerShell?

Je suis particulièrement intéressé File Version, bien que d' autres informations sur la version (qui est, Company, Language, Product Name, etc.) serait utile aussi bien.

Empereur XLII
la source

Réponses:

140

Étant donné que PowerShell peut appeler des classes .NET , vous pouvez effectuer les opérations suivantes:

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

Ou comme indiqué ici sur une liste de fichiers:

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

Ou encore plus agréable comme script: https://jtruher3.wordpress.com/2006/05/14/powershell-and-file-version-information/

Lars Truijens
la source
8
Consultez @Jaykul pour une solution qui ne nécessite pas d'objet .NET. La réponse de IMHO Jaykul aurait dû être sélectionnée comme réponse :)
Thomas Bratt
2
Bien que les autres réponses donnent des commandes plus courtes, toutes celles que j'ai essayées affichent trop d'informations et tronquent le chemin du fichier en "...". La deuxième commande de cette réponse donne exactement ce dont vous avez besoin, fonctionne pour un répertoire de fichiers et se met en forme de manière à ce qu'il soit facile de voir comment le modifier pour renvoyer d'autres informations. Changez simplement le .LegalCopyright dans la commande en .FileVersion.
Dennis
Il s'agit de la version correcte pour les EXE .NET. La réponse de Jaykul n'obtient pas la même version.
ashes999
Ce n'est pas vrai. Regardez get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -forceet comparez le FilePrivatePart à la dernière partie de FileVersion. La FileVersion montre ce qui a été livré à l'origine, et non la version corrigée. Cette commande, en revanche, affiche le numéro de version corrigé: (get-command C: \ Windows \ System32 \ ubpm.dll) .Version
Jaykul
Un meilleur exemple serait le C: \ Windows \ System32 \ Lsasrv.dll récemment patché ... mais la vérité est que (Get-Command ... ).Versionrenvoie la ProductVersion pas la FileVersion , et parfois cela compte. Donc, pour une solution complète qui renvoie réellement la FileVersion mise à jour , consultez l'exemple Update-TypeData dans ma réponse ci-dessous.
Jaykul
170

De nos jours, vous pouvez obtenir le FileVersionInfo à partir de Get-Item ou Get-ChildItem, mais il affichera la FileVersion d'origine du produit expédié, et non la version mise à jour. Par exemple:

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

Fait intéressant, vous pouvez obtenir la ProductVersion mise à jour (corrigée) en utilisant ceci:

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

La distinction que je fais entre "original" et "patché" est essentiellement due à la façon dont la FileVersion est calculée ( voir la documentation ici ). Fondamentalement, depuis Vista, l'API Windows GetFileVersionInfo interroge une partie des informations de version du fichier indépendant de la langue (exe / dll) et la partie non fixe d'un fichier mui spécifique à la langue (qui n'est pas mis à jour chaque fois que les fichiers changent ).

Donc, avec un fichier comme lsasrv (qui a été remplacé en raison de problèmes de sécurité dans SSL / TLS / RDS en novembre 2014), les versions signalées par ces deux commandes (au moins pendant un certain temps après cette date) étaient différentes, et la seconde est la version plus "correcte".

Cependant, bien que ce soit correct dans LSASrv, il est possible que ProductVersion et FileVersion soient différents (c'est courant, en fait). Donc, la seule façon d'obtenir la Fileversion mise à jour directement à partir du fichier d'assemblage est de la créer vous-même à partir des pièces, quelque chose comme ceci:

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

Ou en extrayant les données de ceci:

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

Vous pouvez facilement l'ajouter à tous les objets FileInfo en mettant à jour le TypeData dans PowerShell:

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

Maintenant, chaque fois que vous le faites Get-ChildItemou Get-Itemvous aurez une FileVersionpropriété qui affiche la FileVersion mise à jour ...

Jaykul
la source
10
Et pour en faire l'équivalent de la réponse acceptée de Lars, utilisez simplement(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
rand0m1
1
Je suis intrigué par l' Get-Commandapplication à un fichier dll. Pourriez-vous expliquer son effet?
Stephane Rolland
3
Avertissement Le FileVersionInfo.FileVersion est une représentation sous forme de chaîne qui peut ne pas être à jour. Vous devriez regarder FileVersionInfo.FileMajorPart, FileMinorPart, FileBuildPart, FilePrivatePart. Voir GetFileVersionInfo () renvoie des informations de version de fichier incorrectes
bdeem
1
@Jaykul Pour clarifier mon commentaire / question précédent: la réponse originale montre comment obtenir la ProductVersion dans PowerShell via quelques convolutions intéressantes, car ProductVersion peut être plus indicative que FileVersion. La réponse d'origine ne fait aucune mention de la propriété VersionInfo.ProductVersion, probablement parce que la réponse est antérieure à celle-ci. Un (Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersionmoyen plus récent et plus simple d'obtenir les mêmes informations ProductVersion que celles documentées dans la réponse? Je ne fais pas vraiment confiance à Microsoft pour utiliser le terme de manière ProductVersioncohérente.
Tydaeus
2
@Tydaeus Ce n'est pas nouveau. Vous pouvez le rechercher sur la documentation et voir jusqu'où il remonte (.NET 1.1) 😏. Ma réponse mentionne ProductVersion, mais la version que nous calculons avec tout ce code ScriptProperty est la vraie version de FILE, pas la ProductVersion. Ils sont parfois les mêmes, mais pas toujours. 😔 Et malheureusement, chaque exemple du monde réel que je propose des changements dans la prochaine version de service de Windows 😉 docs.microsoft.com/en-us/dotnet/api
...
50

'dir' est un alias pour Get-ChildItem qui retournera une classe System.IO.FileInfo lorsque vous l'appelez à partir du système de fichiers qui a VersionInfo comme propriété. Alors ...

Pour obtenir les informations de version d'un seul fichier, procédez comme suit:

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     :

Pour plusieurs fichiers ceci:

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
la source
Utile dans la mesure où vous incluez également d'autres métadonnées courantes (comme le nom et la description de l'entreprise).
David Faivre
16

Je préfère installer les extensions de communauté PowerShell et utiliser simplement la fonction Get-FileVersionInfo qu'elle fournit.

Ainsi:

Get-FileVersionInfo MyAssembly.dll

avec une sortie comme:

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

Je l'ai utilisé contre un répertoire entier d'assemblages avec beaucoup de succès.

David Mohundro
la source
12

Je sais que cela a déjà été répondu, mais si quelqu'un est intéressé à taper moins de caractères, je pense que c'est le moyen le plus court d'écrire ceci dans PS v3 +:

ls application.exe | % versioninfo
  • ls est un alias pour Get-ChildItem
  • % est un alias pour ForEach-Object
  • versioninfo voici une manière abrégée d'écrire {$_.VersionInfo}

L'avantage d'utiliser lsde cette manière est que vous pouvez facilement l'adapter pour rechercher un fichier donné dans les sous-dossiers. Par exemple, la commande suivante renverra les informations de version pour tous les fichiers appelés application.exedans les sous-dossiers:

ls application.exe -r | % versioninfo
  • -r est un alias pour -Recurse

Vous pouvez affiner davantage cela en ajoutant -ea silentlycontinuepour ignorer des éléments tels que les erreurs d'autorisation dans les dossiers que vous ne pouvez pas rechercher:

ls application.exe -r -ea silentlycontinue | % versioninfo
  • -ea est un alias pour -ErrorAction

Enfin, si vous obtenez des ellipses (...) dans vos résultats, vous pouvez ajouter | flpour renvoyer les informations dans un format différent. Cela renvoie beaucoup plus de détails, bien que formatés dans une liste, plutôt que sur une ligne par résultat:

ls application.exe -r -ea silentlycontinue | % versioninfo | fl
  • fl est un alias pour Format-List

Je me rends compte que c'est très similaire à la réponse de xcud en cela lset que ce dirsont tous les deux des alias pour Get-ChildItem. Mais j'espère que ma méthode "la plus courte" aidera quelqu'un.

Le dernier exemple pourrait être écrit à la main de la manière suivante:

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

... mais je pense que mon chemin est plus cool et, pour certains, plus facile à retenir. (Mais surtout plus frais).

oliver-clare
la source
11

Une autre façon de le faire est d'utiliser la technique d'accès aux fichiers intégrée:

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

Vous pouvez également obtenir une propriété particulière de VersionInfo, ainsi:

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

C'est assez proche de la technique dir.

Nous s
la source
(get-item \\ "$ nom_ordinateur" \ "C $ \ Program Files \ Symantec AntiVirus \ VPDN_LU.exe"). VersionInfo.FileVersion a fonctionné pour moi. J'avais besoin d'ajouter un nom d'ordinateur à partir d'une boucle.
Tequila
7

Ceci est basé sur les autres réponses, mais c'est exactement ce que je recherchais:

(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
noelicus
la source
Je suis intrigué par l' Get-Commandapplication à un fichier dll. Pourriez-vous expliquer son effet (avant même d'appeler la propriété FileVersionInfo)?
Stephane Rolland
Les fichiers dll contiennent FileVersionInfotout comme les fichiers exe. L'application de cette commande au chemin obtiendra les informations sur la version du fichier!
noelicus
4
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")
EBGreen
la source
4

Je trouve cela utile:

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
la source
Est-ce un VBScript?
macetw
1
Non, c'est powershell
Chriseyre2000
2

Comme EBGreen l'a dit, [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (chemin) fonctionnera, mais rappelez-vous que vous pouvez également obtenir tous les membres de FileVersionInfo, par exemple:

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

Vous devriez pouvoir utiliser tous les membres de FileVersionInfo documentés ici, ce qui vous donnera essentiellement tout ce que vous pourriez souhaiter concernant le fichier.

Adam Haile
la source
1

Voici une méthode alternative. Il utilise Get-WmiObject CIM_DATAFILE pour sélectionner la version.

(Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version
Knuckle-Dragger
la source
en utilisant un chemin de partage avec des espaces dans le nom, j'ai obtenu "La propriété 'Version' est introuvable sur cet objet. Vérifiez que la propriété existe."
AnneTheAgile