用 PowerShell 全自動比對 Windows 驅動版本──DriverCompare 腳本完整分享

想在多台測試機之間快速檢查 BIOS、EC、Windows Build 以及第三方驅動版本差異?這篇文章分享chatGPT製的 DriverCompare 腳本,讓你透過 PowerShell 一鍵產生差異報表,輕鬆掌握版本狀態。


目錄

  1. 需求與設計目標
  2. 資料夾結構
  3. 腳本下載與放置
  4. 使用流程(Baseline → 比對)
  5. driversDiff.csv 欄位解析
  6. 常見錯誤與排除

1 需求與設計目標

  • 第一次執行:自動建立 baseline
  • 後續執行:比對差異並輸出 driversDiff.csv
  • 相容 PowerShell 5.1(移除 ?:?? 語法)

2 資料夾結構

起始只需要用notepad先建立compare-drivers.ps1 & run.bat,其他檔案會自動建立

compare-drivers │ compare-drivers.ps1 │ run.bat │ driversDiff.csv ├─baseline │ baselineDrivers.csv │ baselineInfo.txt └─target currentDrivers.csv systemInfo.txt

3 腳本下載與放置

將整個 compare-drivers 資料夾放進 USB 隨身碟或共用資料夾,即可逐台執行。

4 使用流程

4-1 建立 Baseline

  1. 插上隨身碟 → 執行run.bat

螢幕顯示

Baseline done – move USB to next PC
即完成。

4-2 目標機比對

在其他機器重複執行,完成後會重新產生 driversDiff.csv

5 driversDiff.csv 欄位解析

FlagItemBaselineCurrent說明
DIFFWindows Build1904522631系統版本不同
 XYZ Audio1.0.0.11.0.0.1相同,Flag 留空
DIFFIntel Wi-Fi22.230 目標機缺少此驅動

6 常見錯誤與排除

  • wmic : … not recognized → 近版 Win11 移除 WMIC,可忽略 EC 比對或自行安裝 WMIC。
  • Unexpected token '?' … → 代表載入到舊腳本版本,請更新到本文腳本。
  • 若畫面顯示 !! Error,請打開 DriverCompare_error.log 追蹤細節。

完整 PowerShell 腳本

# DriverCompare – diff Windows / BIOS / EC & 3rd-party drivers
# PowerShell 5.1 compatible (no ??  ?:  ?.)
# Folder layout after first run:
#   baseline\baselineDrivers.csv  baselineInfo.txt
#   target\currentDrivers.csv     target\systemInfo.txt
#   driversDiff.csv

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

# ── paths ───────────────────────────────────────────────
$root         = Split-Path -Parent $MyInvocation.MyCommand.Definition
$baselineDir  = Join-Path $root 'baseline'
$targetDir    = Join-Path $root 'target'
New-Item $baselineDir -ItemType Directory -Force | Out-Null
New-Item $targetDir   -ItemType Directory -Force | Out-Null

$baselineDrv  = Join-Path $baselineDir 'baselineDrivers.csv'
$baselineInfo = Join-Path $baselineDir 'baselineInfo.txt'
$currentDrv   = Join-Path $targetDir   'currentDrivers.csv'
$sysInfoTxt   = Join-Path $targetDir   'systemInfo.txt'
$diffCsv      = Join-Path $root        'driversDiff.csv'
$errLog       = Join-Path $root        'DriverCompare_error.log'

if (Test-Path $currentDrv) { Remove-Item $currentDrv -Force }

function Step($msg){ Write-Host ">>> $msg" -ForegroundColor Cyan }

# ---------- safe WMI/CIM query ----------
function SafeGet($class){
    if (-not (Get-CimClass -ErrorAction SilentlyContinue $class)){
        throw "WMI class [$class] not found."
    }
    try   { Get-CimInstance $class }
    catch { Get-WmiObject   $class }
}

# ---------- EC version ----------
function Get-EC{
    $b = SafeGet Win32_BIOS
    if ($b.EmbeddedControllerMajorVersion){
        '{0}.{1}' -f $b.EmbeddedControllerMajorVersion,$b.EmbeddedControllerMinorVersion
    } else { '' }
}

# ---------- collect drivers ----------
function CollectDrivers($dest){
    Step "Collecting 3rd-party drivers"
    SafeGet Win32_PnPSignedDriver |
      Where-Object { $_.DriverProviderName -ne 'Microsoft' } |
      Select-Object @{n='Device';e={ if($_.DeviceName){ $_.DeviceName.Trim() } else{ 'Unknown' } }},
                    @{n='Version'; e={ $_.DriverVersion }},
                    @{n='Provider';e={ if($_.DriverProviderName){ $_.DriverProviderName.Trim() } else{ 'Unknown' } }},
                    INF |
      Sort-Object Device |
      Export-Csv $dest -NoTypeInformation -Encoding UTF8
}

function NewRow($flag,$item,$base,$cur){
    [pscustomobject]@{ Flag=$flag; Item=$item; Baseline=$base; Current=$cur }
}

# ---------- main ----------
try{
    # create baseline if absent
    if (-not (Test-Path $baselineDrv)){
        Step "Creating baseline"
        CollectDrivers $baselineDrv
        $line = '{0}|{1}|{2}' -f (SafeGet Win32_OperatingSystem).BuildNumber,
                               (SafeGet Win32_BIOS).SMBIOSBIOSVersion,
                               (Get-EC)
        $line | Set-Content $baselineInfo -Encoding UTF8
        Step "Baseline done – move USB to next PC and run again."
        exit
    }

    # current system info
    Step "Gathering current system info"
    $curBuild = (SafeGet Win32_OperatingSystem).BuildNumber
    $curBIOS  = (SafeGet Win32_BIOS).SMBIOSBIOSVersion
    $curEC    = Get-EC
    CollectDrivers $currentDrv
    '{0}|{1}|{2}' -f $curBuild,$curBIOS,$curEC | Set-Content $sysInfoTxt -Encoding UTF8

    # load baseline
    Step "Loading baseline"
    $parts                  = (Get-Content $baselineInfo -Raw).Split('|',3)
    $baseBuild,$baseBIOS,$baseEC = $parts
    $baseTab = Import-Csv $baselineDrv
    $curTab  = Import-Csv $currentDrv

    # deduplicate baseline (keep highest version)
    $baseMap = @{}
    foreach($b in $baseTab){
        $key = "$($b.Device)|$($b.Provider)"
        if ($baseMap[$key]){
            if ([version]$b.Version -gt [version]$baseMap[$key]){ $baseMap[$key]=$b.Version }
        } else { $baseMap[$key]=$b.Version }
    }

    # build diff rows
    $rows = @()

    $flag = ''; if ($baseBuild -ne $curBuild) { $flag = 'DIFF' }
    $rows += NewRow $flag 'Windows Build' $baseBuild $curBuild

    $flag = ''; if ($baseBIOS  -ne $curBIOS ) { $flag = 'DIFF' }
    $rows += NewRow $flag 'BIOS Version'  $baseBIOS  $curBIOS

    $flag = ''; if ($baseEC    -ne $curEC   ) { $flag = 'DIFF' }
    $rows += NewRow $flag 'EC Version'    $baseEC    $curEC

    foreach($c in $curTab){
        $key="$($c.Device)|$($c.Provider)"
        $baseVer=$baseMap[$key]
        $flag=''
        if ($baseVer){
            if ([version]$baseVer -ne [version]$c.Version){ $flag='DIFF' }
            $baseMap.Remove($key)|Out-Null
        } else { $flag='DIFF' }
        if (-not $baseVer){ $baseVer='' }
        $rows += NewRow $flag $c.Device $baseVer $c.Version
    }
    foreach($k in $baseMap.Keys){      # present in baseline but missing now
        $dev,$prov = $k -split '\|',2
        $rows += NewRow 'DIFF' $dev $baseMap[$k] ''
    }

    # output
    Step "Writing diff -> $diffCsv"
    $rows | Export-Csv $diffCsv -NoTypeInformation -Encoding UTF8
    Step "Finished. Review driversDiff.csv and target folder"
}
catch{
    $_ | Out-File $errLog -Append
    Write-Host "!! Error – see DriverCompare_error.log" -ForegroundColor Red
}


完整 run.bat 腳本

@echo off
chcp 65001 > nul
powershell -NoLogo -ExecutionPolicy Bypass ^
  -Command "[Console]::OutputEncoding=[Text.Encoding]::UTF8; & '%~dp0compare-drivers.ps1'"
timeout /t 3 /nobreak > nul

結語

以上就是 DriverCompare 的完整教學與程式碼分享。如有改進想法或問題,歡迎在下方留言交流!

留言

這個網誌中的熱門文章

[旅遊]日本大阪部品(上) - 南海部品