遇到盤點 .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" 欄位名稱,但我沒想出來為什麼會產生這種結果?

Post a comment