用脚本批量导出软件列表的实战指南
📖 目录导读
- 为什么需要批量导出软件列表?
- 脚本导出 vs 手动记录的优劣对比
- Windows系统:PowerShell一键导出
- macOS系统:终端命令高效提取
- Linux系统:包管理器脚本收集
- 跨平台脚本:Python统一方案
- 常见问题与解决方案(Q&A)
- 脚本优化与安全提醒
为什么需要批量导出软件列表?
在日常运维、设备迁移或系统重装时,手动记录软件列表不仅耗时,还容易遗漏,我曾遇到一位IT管理员需要为200台电脑重新部署环境,如果逐台打开“控制面板”截图,至少需要3天,而使用脚本批量导出,5分钟即可完成全部采集。

核心场景包括:
- 系统重装前备份已安装软件清单
- 企业IT资产盘点与合规审计
- 迁移到新电脑时对比软件差异
- 自动化运维中检查软件更新状态
脚本导出 vs 手动记录的优劣对比
| 方式 | 耗时(100台电脑) | 准确性 | 可复用性 | 技术要求 |
|---|---|---|---|---|
| 手动记录 | 8-10小时 | 低(易漏) | 低 | 无 |
| 截图保存 | 6小时 | 中(难整理) | 低 | 无 |
| 脚本批量导出 | 10分钟 | 高 | 高 | 需基础命令知识 |
脚本方法在效率和准确性上优势明显,即使需要学习基础命令,长期看仍是最优选择。
Windows系统:PowerShell一键导出
Windows系统自带PowerShell,无需安装额外工具,以下脚本可导出所有已安装软件(含商店应用):
# 导出传统Win32软件 Get-WmiObject -Class Win32_Product | Select-Object Name, Version, Vendor, InstallDate | Export-Csv -Path "C:\software_list.csv" -NoTypeInformation # 导出Windows商店应用(现代应用) Get-AppxPackage | Select-Object Name, Version, Publisher | Export-Csv -Path "C:\store_apps.csv" -NoTypeInformation
进阶版:合并两个结果,并过滤掉系统组件:
$win32 = Get-WmiObject Win32_Product | Where-Object {$_.Name -notlike "*Microsoft*"} | Select-Object Name, Version, Vendor
$store = Get-AppxPackage | Where-Object {$_.Publisher -notlike "*Microsoft*"} | Select-Object Name, Version, Publisher
$all = $win32 + $store
$all | Export-Csv "C:\my_software.csv" -NoTypeInformation
Write-Host "导出完成!文件位置:C:\my_software.csv"
运行方式:以管理员身份打开PowerShell,粘贴脚本执行,导出的CSV文件可用Excel打开,便于筛选和统计。
macOS系统:终端命令高效提取
macOS用户无需第三方工具,终端命令即可完成:
# 方法1:使用pkgutil(只显示pkg安装的软件)
pkgutil --pkgs | awk -F"." '{print $NF}' | sort | uniq > ~/Desktop/mac_software.txt
# 方法2:从Applications目录提取(更全面)
ls /Applications/ | grep -v "Siri\|Launchpad\|System" | sed 's/.app//' > ~/Desktop/app_list.txt
推荐脚本:综合两种方法,并提取版本信息:
#!/bin/bash
echo "名称,版本,安装方式" > ~/Desktop/mac_software.csv
ls /Applications/ | while read app; do
name=${app%.app}
plist="/Applications/$app/Contents/Info.plist"
if [ -f "$plist" ]; then
version=$(defaults read "$plist" CFBundleShortVersionString 2>/dev/null || echo "未知")
echo "$name,$version,拖拽安装" >> ~/Desktop/mac_software.csv
fi
done
echo "导出完成,打开 ~/Desktop/mac_software.csv 查看"
注意:macOS从Catalina开始对系统卷有保护,部分系统App可能无法访问,建议配合Homebrew管理的软件列表(brew list --versions)一同导出。
Linux系统:包管理器脚本收集
Linux发行版众多,但包管理器命令逻辑相似,以下脚本适配Debian/Ubuntu和CentOS/RHEL:
#!/bin/bash
# 检测系统类型
if command -v dpkg &> /dev/null; then
# Debian/Ubuntu系
dpkg -l | grep '^ii' | awk '{print $2, $3}' > ~/linux_packages.txt
elif command -v rpm &> /dev/null; then
# RHEL/CentOS系
rpm -qa --queryformat '%{NAME} %{VERSION}\n' > ~/linux_packages.txt
else
echo "未识别的包管理器"
exit 1
fi
echo "已导出到 ~/linux_packages.txt,共 $(wc -l < ~/linux_packages.txt) 个软件"
统一脚本:同时支持apt和yum:
packages=()
if [ -f /etc/debian_version ]; then
mapfile -t packages < <(dpkg-query -W -f='${Package} ${Version}\n')
elif [ -f /etc/redhat-release ]; then
mapfile -t packages < <(rpm -qa --queryformat '%{NAME} %{VERSION}\n')
fi
printf "%s\n" "${packages[@]}" > ~/full_software_list.txt
跨平台脚本:Python统一方案
如果需管理多平台环境(如混合网络),Python脚本可一站式解决:
import platform
import subprocess
import csv
import os
def get_software_windows():
import winreg
software_list = []
key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path) as key:
for i in range(winreg.QueryInfoKey(key)[0]):
subkey_name = winreg.EnumKey(key, i)
with winreg.OpenKey(key, subkey_name) as subkey:
try:
name = winreg.QueryValueEx(subkey, "DisplayName")[0]
version = winreg.QueryValueEx(subkey, "DisplayVersion")[0]
software_list.append((name, version))
except:
pass
return software_list
def get_software_macos():
import os
apps = os.listdir("/Applications")
return [(app.replace(".app",""), "未知") for app in apps]
def get_software_linux():
result = subprocess.run(["dpkg-query", "-W"], capture_output=True, text=True)
return [line.split() for line in result.stdout.strip().split("\n") if line]
# 主执行
system = platform.system()
if system == "Windows":
software = get_software_windows()
elif system == "Darwin":
software = get_software_macos()
else:
software = get_software_linux()
with open("software_export.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["软件名", "版本"])
writer.writerows(software)
print(f"已导出 {len(software)} 个软件到 software_export.csv")
优点:一次编写,多平台运行,适合需要统一输出格式的企业环境。
常见问题与解决方案(Q&A)
Q1:脚本执行时提示“权限不足”怎么办?
A:Windows需以管理员身份运行PowerShell;macOS/Linux需在命令前加sudo,注意:频繁使用sudo会带来安全风险,建议仅在需要时使用。
Q2:导出列表中包含大量系统组件,如何快速过滤?
A:使用Where-Object(Windows)或grep -v(macOS/Linux)过滤。Get-WmiObject Win32_Product | Where-Object {$_.Vendor -notlike "*Microsoft*"},也可按“软件发布者”分类筛选。
Q3:导出后如何批量重新安装?
A:Windows可使用winget(需Win10/11+),Get-Content C:\software_list.csv | ForEach-Object { winget install $_ },macOS用户可配合Homebrew(xargs brew install < mac_software.txt),Linux用户直接用包管理器安装:xargs -a linux_packages.txt apt install -y。
Q4:列表导出后发现时间戳不对,如何调整格式?
A:Windows的InstallDate为原始格式,可用Get-Date转换:$date = Get-Date "20241201000000.000000-000",也可在SQL查询中直接用FORMAT函数。
Q5:脚本输出乱码(中文显示为问号)如何解决?
A:PowerShell中执行前添加[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8,Linux终端确认locale设置为zh_CN.UTF-8,另可指定CSV编码:Export-Csv -Encoding UTF8。
脚本优化与安全提醒
优化建议:
- 添加时间戳:在导出文件名中加入日期,避免覆盖历史记录(例:
software_list_$(Get-Date -Format yyyyMMdd).csv)。 - 增量对比:使用
Compare-Object(PowerShell)或diff(Linux)对比两次导出的差异,快速定位新增/删除软件。 - 静默执行:在脚本开头加入
$ProgressPreference = 'SilentlyContinue',避免弹出进度条打断自动化流程。
安全警示:
- 脚本中请勿硬编码管理员密码,如需要权限提升,使用
RunAs或sudo交互式输入。 - 导出的CSV文件可能包含敏感信息(如软件密钥、用户权限),建议存储在权限受限的目录,或加密后传输。
- 从互联网复制脚本时,务必检查代码中是否有恶意片段(如隐藏的下载、删除命令),先在一台测试机上运行。