
在 Windows 环境下进行批量装机或重装系统后,软件部署通常面临以下痛点:
.bat)难以处理静默参数不统一、进程卡死等异常情况。基于此,编写了一个 PowerShell 脚本 (AutoInstall.ps1),采用 “Winget 在线 + Local 离线” 的混合部署策略,并加入了进程监控和注册表查重机制。
脚本将部署流程分为两个阶段,逻辑解耦:
my_apps.txt 配置文件,调用系统内置 winget 部署常用软件(Chrome, VSCode 等)。支持通过标签 # [SOURCE: msstore] 动态切换下载源。Local_Apps 目录,根据文件后缀(.exe/.msi/文件夹)自动匹配安装策略。为了防止重复安装,脚本在本地部署阶段引入了预检查机制。
HKLM 和 HKCU 下的 Uninstall 注册表项,构建已安装软件名称列表。powershell# 获取系统已安装软件列表 function Get-InstalledAppNames { $paths = @( "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" ) $names = @() foreach ($path in $paths) { Get-ItemProperty $path -ErrorAction SilentlyContinue | ForEach-Object { if ($_.DisplayName) { $names += $_.DisplayName } } } return $names }
在使用 winget 或调用外部 exe 时,可能会出现网络挂起或安装程序卡死的情况。
脚本放弃了简单的 Wait-Process,改用循环轮询的方式监控进程运行时间。一旦超过阈值(默认 10 分钟),强制终止进程。
powershell# 启动进程并获取对象 $proc = Start-Process -FilePath $exe -ArgumentList $args -PassThru -NoNewWindow $startTime = Get-Date while (-not $proc.HasExited) { Start-Sleep -Seconds 2 # 计算运行时长 if (((Get-Date)-$startTime).TotalMinutes -ge $TimeLimitMinutes) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue Write-Host " [!] 任务超时,强制熔断。" -ForegroundColor Red break } }
本地文件通常只有英文文件名(如 SoftCnKiller.exe)。脚本内置了一个哈希表(HashTable)字典,在运行时动态匹配文件名并输出中文说明,提升日志可读性。
powershell$AppDict = @{ "finalshell" = "SSH连接/服务器管理" "softcnkiller" = "流氓软件清理工具" "wiztree" = "磁盘空间分析" # ... }
为了保证脚本的可移植性(Portable),采用相对路径结构:
textDeploy_Tool_V33/ │ ├── 一键启动.bat # 引导层:负责提权和绕过执行策略 ├── AutoInstall.ps1 # 逻辑层:PowerShell 核心代码 ├── my_apps.txt # 配置层:Winget 软件清单 │ └── Local_Apps/ # 数据层:存放本地安装包 ├── setup_v1.0.exe └── PortableTool/ # 支持直接复制绿色软件目录
脚本针对几种常见的安装失败场景做了处理:
/S 或 /silent 参数。如果进程快速退出且未成功(依据返回码),脚本会提示用户可能需要手动介入,但不会中断整个流程。Show-Header 函数,基于字符字节宽度计算 Padding,确保日志输出整洁。my_apps.txt 添加需要的 Winget ID;将离线包放入 Local_Apps。一键启动.bat。下载地址: 整合包下载地址
本文作者:小转圈
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!