คุณจะรับข้อมูลรุ่นจาก.dll
หรือ.exe
ไฟล์ใน PowerShell ได้อย่างไร
ผมสนใจเฉพาะในFile Version
แต่ข้อมูลรุ่นอื่น ๆ (นั่นคือCompany
, Language
, Product Name
ฯลฯ ) จะเป็นประโยชน์เช่นกัน
คุณจะรับข้อมูลรุ่นจาก.dll
หรือ.exe
ไฟล์ใน PowerShell ได้อย่างไร
ผมสนใจเฉพาะในFile Version
แต่ข้อมูลรุ่นอื่น ๆ (นั่นคือCompany
, Language
, Product Name
ฯลฯ ) จะเป็นประโยชน์เช่นกัน
คำตอบ:
เนื่องจาก 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/
get-item C:\Windows\System32\ubpm.dll | % VersionInfo | fl * -force
และเปรียบเทียบ FilePrivatePart กับส่วนสุดท้ายของ FileVersion FileVersion แสดงสิ่งที่จัดส่งมา แต่ดั้งเดิมไม่ใช่เวอร์ชันที่ได้รับการแก้ไข คำสั่งนี้ในมืออื่น ๆ , การแสดงหมายเลขรุ่น patched: (ได้รับคำสั่ง C: \ Windows \ System32 \ ubpm.dll) .Version
(Get-Command ... ).Version
คืนProductVersionไม่ใช่FileVersionและบางครั้งก็สำคัญ ดังนั้นสำหรับโซลูชันเต็มรูปแบบที่ส่งคืนFileVersion ที่อัปเดตจริงให้ตรวจสอบตัวอย่าง Update-TypeData ในคำตอบของฉันด้านล่าง
ทุกวันนี้คุณสามารถรับ 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 ที่อัปเดต ...
(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
Get-Command
ใช้กับไฟล์ dll คุณช่วยอธิบายเกี่ยวกับผลกระทบของมันได้อย่างละเอียดหรือไม่?
(Get-Item C:\Windows\System32\Lsasrv.dll).VersionInfo.ProductVersion
วิธีที่ใหม่กว่าที่ง่ายกว่าในการรับข้อมูล ProductVersion เช่นเดียวกับที่บันทึกไว้ในคำตอบหรือไม่ ฉันไม่เชื่อถือ Microsoft ให้ใช้คำนี้ProductVersion
อย่างสม่ำเสมอ
'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
ฉันต้องการติดตั้งPowerShell Community Extensionsและเพียงแค่ใช้ฟังก์ชัน Get-FileVersionInfo ที่มีให้
ชอบมาก
Get-FileVersionInfo MyAssembly.dll
ด้วยผลลัพธ์เช่น:
ProductVersion FileVersion FileName -------------- ----------- -------- 1.0.2907.18095 1.0.2907.18095 C: \ Path \ To \ MyAssembly.dll
ฉันใช้มันกับไดเรกทอรีทั้งหมดของการชุมนุมที่ประสบความสำเร็จ
ฉันรู้ว่าสิ่งนี้ได้รับคำตอบแล้ว แต่ถ้าใครสนใจพิมพ์ตัวอักษรน้อยลงฉันเชื่อว่านี่เป็นวิธีที่สั้นที่สุดในการเขียนใน 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
... แต่ฉันคิดว่าวิธีการของฉันเจ๋งกว่าและง่ายกว่าที่จะจำได้ (แต่ส่วนใหญ่เย็นกว่า)
อีกวิธีหนึ่งในการทำคือใช้เทคนิคการเข้าถึงไฟล์ในตัว:
(get-item .\filename.exe).VersionInfo | FL
นอกจากนี้คุณยังสามารถนำคุณสมบัติเฉพาะออกจาก VersionInfo ได้เช่น:
(get-item .\filename.exe).VersionInfo.FileVersion
นี่ค่อนข้างใกล้กับเทคนิค dir
นี่ขึ้นอยู่กับคำตอบอื่น ๆ แต่เป็นสิ่งที่ฉันเป็นหลังจาก:
(Get-Command C:\Path\YourFile.Dll).FileVersionInfo.FileVersion
Get-Command
ใช้กับไฟล์ dll คุณสามารถอธิบายรายละเอียดเกี่ยวกับเอฟเฟกต์ของมันได้ (ก่อนที่จะเรียกใช้ FileVersionInfo ของคุณสมบัติ)
FileVersionInfo
เช่นเดียวกับไฟล์ exe ทำ การใช้คำสั่งนี้กับพา ธ จะได้รับข้อมูลเวอร์ชันของไฟล์!
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("Path\To\File.dll")
ฉันพบว่ามีประโยชน์นี้:
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
}
ดังที่ EBGreen กล่าวว่า [System.Diagnostics.FileVersionInfo] :: GetVersionInfo (เส้นทาง) จะใช้งานได้ แต่โปรดจำไว้ว่าคุณสามารถรับสมาชิกทั้งหมดของ FileVersionInfo ได้เช่น:
[System.Diagnostics.FileVersionInfo]::GetVersionInfo(path).CompanyName
คุณควรจะสามารถใช้สมาชิกทุกคนของ FileVersionInfo ที่จัดทำเอกสารไว้ที่นี่ซึ่งจะทำให้คุณได้รับสิ่งที่คุณต้องการเกี่ยวกับไฟล์
นี่คือวิธีการทางเลือก มันใช้ Get-WmiObject CIM_DATAFILE เพื่อเลือกรุ่น
(Get-WmiObject -Class CIM_DataFile -Filter "Name='C:\\Windows\\explorer.exe'" | Select-Object Version).Version