使用Perl检测已安装PowerShell模块 实现Windows设备自动更新
实现方案
- 核心实现逻辑:通过Perl调用PowerShell检测命令,捕获进程退出码判断模块是否已安装/导入,避免重复执行安装操作,同时兼容不同系统环境的执行逻辑,新增错误捕获避免脚本无响应或执行失败无提示。
修改后的完整代码
print "Installing new updates\n"; my ( $osvername, $major, $minor, $id ) = Win32::GetOSVersion(); if($major == 10 ) { my $ps_path = 'C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe'; # 修改PowerShell执行策略 system("$ps_path -command Set-ExecutionPolicy RemoteSigned -force") >> 8 == 0 or die "修改PowerShell执行策略失败"; # 校验PSWindowsUpdate模块是否已安装 `"$ps_path" -command "if (Get-Module -ListAvailable -Name PSWindowsUpdate) {exit 0} else {exit 1}"`; my $module_installed = $? >> 8; if ($module_installed != 0) { # 信任PSGallery源避免安装时弹出确认框卡住 system("$ps_path -command Set-PSRepository -Name PSGallery -InstallationPolicy Trusted") >> 8 == 0 or die "设置PSGallery源信任失败"; # 安装模块,指定全局生效避免权限问题 system("$ps_path -command Install-Module PSWindowsUpdate -Force -AllowClobber -Scope AllUsers") >> 8 == 0 or die "安装PSWindowsUpdate模块失败"; } # 校验模块可正常导入、命令可用 `"$ps_path" -command "Import-Module PSWindowsUpdate -Force; if (Get-Command Get-WindowsUpdate -ErrorAction SilentlyContinue) {exit 0} else {exit 1}"`; my $module_available = $? >> 8; die "PSWindowsUpdate模块导入失败" if $module_available != 0; # 执行系统更新 system("$ps_path -command Get-WindowsUpdate -Install -AcceptAll") >> 8 == 0 or warn "部分更新安装失败"; # 恢复默认执行策略 system("$ps_path -command Set-ExecutionPolicy Default -force"); } else { system("$gRootDir\\Tools\\WUInstall.exe /install") >> 8 == 0 or die "WUInstall执行更新失败"; }
关键修改说明
- 模块安装校验:通过
Get-Module -ListAvailable判断模块是否已存在,仅未安装时才执行安装逻辑,减少冗余操作 - 导入有效性校验:安装完成后验证
Get-WindowsUpdate命令可正常调用,避免模块安装异常、依赖缺失导致后续操作失败 - 错误捕获:所有system调用都校验返回码,执行失败直接抛出明确错误,方便定位问题
- 兼容性优化:新增PSGallery源信任配置、指定模块安装范围为所有用户,避免首次运行、权限不足导致的安装卡住问题
内容的提问来源于stack exchange,提问作者StupidScienceGuy
相关产品推荐
相关产品推荐

