怎样用脚本批量导出软件列表?

wen 实用脚本 2

用脚本批量导出软件列表的实战指南

📖 目录导读


为什么需要批量导出软件列表?

在日常运维、设备迁移或系统重装时,手动记录软件列表不仅耗时,还容易遗漏,我曾遇到一位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


脚本优化与安全提醒

优化建议:

  1. 添加时间戳:在导出文件名中加入日期,避免覆盖历史记录(例:software_list_$(Get-Date -Format yyyyMMdd).csv)。
  2. 增量对比:使用Compare-Object(PowerShell)或diff(Linux)对比两次导出的差异,快速定位新增/删除软件。
  3. 静默执行:在脚本开头加入$ProgressPreference = 'SilentlyContinue',避免弹出进度条打断自动化流程。

安全警示:

  • 脚本中请勿硬编码管理员密码,如需要权限提升,使用RunAssudo交互式输入。
  • 导出的CSV文件可能包含敏感信息(如软件密钥、用户权限),建议存储在权限受限的目录,或加密后传输。
  • 从互联网复制脚本时,务必检查代码中是否有恶意片段(如隐藏的下载、删除命令),先在一台测试机上运行。

抱歉,评论功能暂时关闭!