怎么用脚本获取安装软件列表

wen 实用脚本 2

本文目录导读:

怎么用脚本获取安装软件列表

  1. 目录导读
  2. 为什么需要自动获取软件安装列表?
  3. 主流系统脚本方案对比
  4. 实战:PowerShell脚本获取Windows已安装软件
  5. 实战:Bash脚本获取Linux软件列表
  6. 实战:macOS终端命令导出应用清单
  7. 脚本输出格式优化与远程采集
  8. 常见问题与解决方案(Q&A)
  9. 自动化脚本的进阶技巧

脚本自动化采集与导出全攻略

目录导读

  • 为什么需要自动获取软件安装列表?
  • 主流系统脚本方案对比(Windows/macOS/Linux)
  • 实战:PowerShell脚本获取Windows已安装软件
  • 实战:Bash脚本获取Linux软件列表
  • 实战:macOS终端命令导出应用清单
  • 脚本输出格式优化与远程采集
  • 常见问题与解决方案(Q&A)
  • 自动化脚本的进阶技巧

为什么需要自动获取软件安装列表?

在日常系统运维、安全审计、软件资产盘点或迁移前,手动记录几百台电脑的软件列表不仅低效,而且容易遗漏,脚本化采集能实现:

  • 批量审计:快速检查未授权软件或过时版本
  • 环境复现:迁移系统时一键导出依赖列表
  • 自动化报告:结合定时任务生成合规报表

你可能面临的问题:Windows注册表路径不同、macOS签名的限制、Linux包管理器的差异——这些都可以通过特定脚本解决。


主流系统脚本方案对比

系统类型 推荐脚本语言 核心命令/接口 输出示例
Windows PowerShell Get-WmiObject,Get-ItemProperty 名称、版本、安装路径
Linux (APT) Bash dpkg -l 包名、版本、架构
Linux (RPM) Bash (YUM/DNF) rpm -qa 同上
macOS Bash + system_profiler system_profiler SPApplicationsDataType 名称、版本、来源

兼容性警示:Windows旧版系统(如Win7)需改用WMI查询;macOS Big Sur后部分应用签名变更。


实战:PowerShell脚本获取Windows已安装软件

核心代码(建议管理员身份运行)

# 方法一:通过注册表(可靠度高)
$software = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* |
            Where-Object { $_.DisplayName -ne $null } |
            Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
$software | Export-Csv -Path "Windows_Software_List.csv" -NoTypeInformation -Encoding UTF8
# 方法二:通过Win32_Product(慢但含更多元数据)
# Get-WmiObject Win32_Product | Select-Object Name, Version, Vendor

优化要点

  • 过滤系统组件:添加 Where-Object {$_.DisplayName -notlike "KB*"} 排除Windows更新
  • 识别64位软件:同时扫描 HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
  • 远程批量执行:在Invoke-Command中嵌套脚本,指定多台计算机名称

注意:Win32_Product类会触发软件配置检查,生产环境慎用(可能引发MSI重新配置)。


实战:Bash脚本获取Linux软件列表

Debian/Ubuntu系列

#!/bin/bash
dpkg-query -f '${Package}\t${Version}\t${Architecture}\n' -W > linux_apt_software.txt
# 或更详细:dpkg -l | grep '^ii' | awk '{print $2, $3}'

Red Hat/CentOS/Fedora系列

#!/bin/bash
rpm -qa --queryformat '%{NAME}\t%{VERSION}\t%{ARCH}\n' > linux_rpm_software.txt
# 若需含安装日期:rpm -qa --last

跨发行版谨慎方案

使用 which 检测常见包管理器,动态切换:

if command -v dpkg &> /dev/null; then
    dpkg -l > list.txt
elif command -v rpm &> /dev/null; then
    rpm -qa > list.txt
fi

高级功能:结合 grep -vE "^(lib|perl)" 过滤库文件,只保留用户可见应用。


实战:macOS终端命令导出应用清单

macOS因沙箱机制,应用信息分为三类:

获取系统记录的应用

system_profiler SPApplicationsDataType -xml | plutil -convert json -o - | jq '.SPApplicationsDataType[] | {appName: ._name, version: .version, path: .path}'
# 若未安装jq,可改用:system_profiler SPApplicationsDataType | grep -E "Location:|Version:"

获取用户级应用

find /Applications -maxdepth 2 -name "*.app" -exec sh -c 'echo "{}: $(mdls -name kMDItemVersion {} | cut -d= -f2)"' \;

基于Homebrew的管理包

brew list --versions > homebrew_software.csv
# 注意:只记录通过brew安装的命令行工具

常见误区system_profiler 不会列出所有自主安装的免签名应用(如从网上下载的未签名dmg文件)。


脚本输出格式优化与远程采集

标准化CSV生成(以Windows为例)

$out = @()
$regPaths = @(
    "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*",
    "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
foreach ($path in $regPaths) {
    $out += Get-ItemProperty $path -ErrorAction SilentlyContinue |
            Where-Object { $_.DisplayName } |
            Select-Object @{N='System';E={'Windows'}}, DisplayName, DisplayVersion, Publisher
}
$out | Export-Csv -Path "unified.csv" -NoTypeInformation

远程批量采集(Linux示例)

for host in server1 server2 server3; do
    ssh $host "dpkg -l | grep '^ii'" > "$host.txt"
done
# 若要并行加速,加入:& 背景进程

常见问题与解决方案(Q&A)

Q1:为什么Windows脚本有时会漏掉软件?
A:某些软件使用非标准注册路径(如 HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall),需补充扫描当前用户配置单元。

Q2:获取的版本号与实际不符怎么办?
A:注册表中的 DisplayVersion 可能缺失,可尝试 Get-WmiObject Win32_Product(注意性能影响),Linux用户可执行 apt-cache policy 包名 做二次验证。

Q3:如何禁止脚本输出系统自带组件?
A:增加过滤词库,Where-Object {$_.DisplayName -notmatch "Microsoft Visual C\+\+|DirectX|Windows"}

Q4:macOS导出的列表包含Adobe全家桶,但路径不一致?
A:Adobe应用常位于 /Applications/Adobe*/Library/Application Support/Adobe,建议配合 find 命令全面扫描。

Q5:脚本能否导出安装日期?
A:Windows注册表含 InstallDate 键,但格式为YYYYMMDD字符串;Linux可使用 rpm -qi 包名 | grep Install Date;macOS应用日期隐藏在 com.apple.quarantine 扩展属性中。

Q6:如何保护导出的密码或密钥?
A:脚本不应采集敏感数据,若需认证,考虑使用SSH密钥登录远程主机,并确保CSV文件权限为 600(仅所有者读写)。


自动化脚本的进阶技巧

长期监控与变更日志

使用以下策略捕捉软件变动:

  • Windows:注册表监控 WMI Event Subscription,当Uninstall子键变化时触发脚本
  • Linuxinotifywait 监控 /var/lib/dpkg/info/var/lib/rpm
  • 统一方案:每日生成快照,用 diff 对比前后文件

企业级集成

  • 将脚本嵌入 Microsoft IntuneSCCM 的合规策略
  • Linux:通过 Ansiblepackage_facts 模块直接获取
  • 输出JSON格式,方便对接 ELKSplunk
$software | ConvertTo-Json | Out-File "sw.json"

安全注意事项

  • 避免在非信任网络中执行未经签名的PowerShell脚本(可启用 -ExecutionPolicy RemoteSigned
  • Linux脚本避免使用裸 eval$(命令) 处理用户输入
  • 导出文件定期清理,防止信息泄露

通过以上脚本方案,你可以实现从单机到集群、从手动到自动的软件资产采集。记住:脚本的核心价值在于减少重复劳动,但务必验证输出数据的完整性,建议先在测试环境运行,并对比系统自带工具(如“添加/删除程序”)的结果,当采集规模超过100台时,考虑引入诸如 saltstackansible 的集中管理平台。

(参考来源:Microsoft Docs关于Uninstall注册表路径的说明;Linux Foundation的dpkg/rpm手册;Apple Developer的system_profiler文档)

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