在系統管理工作中,經常需要匯出電腦上已安裝的軟體清單。不過單純使用 Win32_Product 類別往往會漏掉許多軟體,因為現代軟體經常使用自己的安裝程式而非 Windows Installer。本文將介紹如何使用更全面的方法來取得完整的軟體清單。

登錄檔是更可靠的來源

Windows 已安裝軟體的資訊主要存在三個登錄檔位置:

  • HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall — 機器範圍的 64 位元安裝
  • HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall — 機器範圍的 32 位元安裝
  • HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall — 目前使用者範圍的安裝(Winget user scope、VS Code user installer 等)

只掃前兩條會系統性漏掉 per-user 安裝。這三個路徑合起來才接近「完整清單」,比 Win32_Product 涵蓋範圍更廣。

完整的 PowerShell 腳本

執行前確認 PowerShell 執行原則允許本機腳本。若出現「無法載入腳本」錯誤,以管理員開啟 PowerShell 執行一次 Set-ExecutionPolicy RemoteSigned,或直接將腳本內容貼到互動式 PowerShell 視窗執行(不受執行原則限制)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 定義要掃描的登錄檔路徑(含 per-user 安裝位置)
$RegPaths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*"
)

# 取得已安裝的軟體清單
$InstalledSoftware = foreach ($Path in $RegPaths) {
# 從登錄檔讀取軟體資訊(-ErrorAction SilentlyContinue 避免路徑不存在時報錯)
Get-ItemProperty $Path -ErrorAction SilentlyContinue |
# 選擇需要的欄位
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
# 過濾掉沒有名稱的項目(通常是更新檔)
Where-Object { $_.DisplayName }
}

# 依照軟體名稱排序並移除重複項目
# 注意:Sort-Object -Unique 以 DisplayName 為唯一鍵,同名不同版本只保留一筆(通常是第一筆)
$InstalledSoftware = $InstalledSoftware |
Sort-Object DisplayName -Unique

# 設定輸出檔案路徑,存在桌面
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$OutputFile = Join-Path $DesktopPath "installed_software_complete.csv"

# 匯出成 CSV 檔案
# 注意:Windows PowerShell 5.1 的 -Encoding UTF8 輸出帶 BOM 的 UTF-8,PowerShell 7+ 則預設無 BOM
$InstalledSoftware |
Select-Object @{N='名稱';E={$_.DisplayName}},
@{N='版本';E={$_.DisplayVersion}},
@{N='發布者';E={$_.Publisher}},
@{N='安裝日期';E={$_.InstallDate}} |
Export-Csv -Path $OutputFile -NoTypeInformation -Encoding UTF8

Write-Host "軟體清單已匯出至: $OutputFile"

腳本說明

  1. 登錄檔路徑

    • 掃描三個路徑:HKLM 64 位元、HKLM 32 位元(WOW6432Node)、HKCU per-user
    • -ErrorAction SilentlyContinue 避免路徑不存在(例如純 32 位元環境缺少 WOW6432Node)時中斷執行
  2. 讀取軟體資訊

    • 使用 Get-ItemProperty 讀取登錄檔內容
    • 選擇重要欄位:名稱、版本、發布者、安裝日期
    • 過濾掉沒有名稱的項目(通常是更新檔或系統元件)
    • 改用 foreach 直接收集結果,避免迴圈內 += 反覆重新配置陣列
  3. 資料處理

    • 合併三個路徑的資料後依名稱排序
    • -Unique 以 DisplayName 為唯一鍵去重;若同一軟體在 HKLM 與 HKCU 都有登錄,只保留一筆
  4. 匯出資料

    • 將欄位名稱改為中文,方便閱讀
    • 匯出成 CSV 格式,存放在桌面
    • Windows PowerShell 5.1(powershell.exe)的 -Encoding UTF8 輸出帶 BOM 的 UTF-8,用 Excel 直接雙擊開啟通常可正常顯示中文;PowerShell 7+(pwsh.exe)則預設輸出無 BOM 的 UTF-8,請依執行環境選擇

執行結果

執行後會在桌面產生 installed_software_complete.csv 檔案,打開後可以看到類似以下的內容:

名稱 版本 發布者 安裝日期
Adobe Creative Cloud 5.11.0.522 Adobe Inc. 20231201
Google Chrome 120.0.6099.130 Google LLC 20231215
Microsoft Office 16.0.17201.20290 Microsoft Corporation 20230601
PyCharm 2023.3 233.11799.298 JetBrains s.r.o. 20231220
Visual Studio Code 1.85.1 Microsoft Corporation 20231218

注意事項

  1. 讀取登錄檔通常不需要管理員權限;若環境有群組原則限制或需要掃描其他使用者的 HKCU,則需要提權
  2. 某些軟體可能沒有完整的安裝資訊
  3. 安裝日期格式可能因軟體而異

進階使用

如果需要更多資訊,可以修改 Select-Object 的欄位,例如:

1
2
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate, 
InstallLocation, UninstallString, EstimatedSize

這樣就能同時匯出:

  • 安裝路徑 (InstallLocation)
  • 解除安裝指令 (UninstallString)
  • 預估大小 (EstimatedSize)

參考資料