PowerShell 小工具 - 盤點及比較 DLL 版本差異
2 |
遇到盤點 .NET 組件(.dll)版號比對多個環境版本差異的需求,看起來是 PowerShell 的主場,試寫一下,比想像還簡單:
param (
[Parameter(Mandatory = $true)]
[string]
$path
)
Get-ChildItem -Path $path -Filter *.dll -Recurse |
ForEach-Object {
[PSCustomObject] @{
File = $_.FullName;
FileVer = $_.VersionInfo.FileVersion;
FileSize = $_.Length.ToString("n0");
CreateTime = $_.CreationTime.ToString('yyyy-MM-dd HH:mm');
UpdateTime = $_.LastWriteTime.ToString('yyyy-MM-dd HH:mm')
}
} |
ConvertTo-Csv -NoTypeInformation
原理很簡單,Get-ChildItem 找出目錄下(包含子目錄)所有 dll,從檔案資料物件取得路徑、大小、建立時間、最後修改時間,VersionInfo 屬性則 FileVersion 可以取得版號 (實務上有時會不動 AssemblyVersion 只改 AssemblyFileVersion 故 File Version 更能反映版本不同,參考:關於 AssemblyVersion 的一點小事),將這些資料包成 PSCustomObject,最後轉成 CSV。
接上 | Out-File -Path check.csv -Encoding UTF8 可存檔改用 Excel 開啟方便利用。
【同場加映】
那可以比較兩個 csv 的差異嗎?這種雜耍用 LINQ 我寫很多了,這回練習用 PowerShell 實現。
param (
[Parameter(Mandatory = $true)]
[string]
$srcPath,
[Parameter(Mandatory = $true)]
[string]
$dstPath
)
$ErrorActionPreference = "STOP"
$src = Import-Csv $srcPath
$dst = Import-Csv $dstPath
$srcDict = @{ }
$dstDict = @{ }
$src | ForEach-Object {
$srcDict[$_.File] = $_
}
$dst | ForEach-Object {
$dstDict[$_.File] = $_
if (!$srcDict[$_.File]) {
Wirte-Output "Missing in source - $($_.File)"
}
}
$src | ForEach-Object {
if (!$dstDict[$_.File]) {
Write-Output "Missing in destination - $($_.File)"
}
else {
$srcObj = $srcDict[$_.File];
$dstObj = $dstDict[$_.File];
$diff = @();
$srcObj.PSObject.Properties | ForEach-Object {
$propName = $_.Name
if ($_.Value -ne $dstObj.$propName) {
$diff += " * $propName : $($_.Value) -> $($dstObj.$propName))"
}
}
if ($diff.Length -gt 0) {
Write-Output "Changed on $($_.File)";
Write-Output ($diff -join "`n")
Write-Output ""
}
}
}
弱型別有弱型別的好,但不打錯字會死的我,又因為錯字卡好久,總算成功了。
Example of listing and comparing version difference of DLLs.
Comments
# by aple
您好 請問一下,我直接複製貼上製作List-DllVersionInfo.ps1後執行,輸出結果地抬頭如下 "IsReadOnly","IsFixedSize","IsSynchronized","Keys","Values","SyncRoot","Count" 不知道是我有什麼環境設定不對嗎?
# by Jeffrey
to aple, 你的 PS 版本是?(用 $PSVersionTable 查看) 移除參數 -NoTypeInformation 是否看到 #TYPE System.Collections.Hashtable ? @{} | ConvertTo-Csv 會出現你說的 "IsReadOnly","IsFixedSize","IsSynchronized","Keys","Values","SyncRoot","Count" 欄位名稱,但我沒想出來為什麼會產生這種結果?