# 前言
最近在协助前东家实施一个 EPM 操作系统部署的项目,我主要帮忙编写相关自动化部署脚本,期间遇到两个比较有意思的脚本运行问题,在此记录一下,或许可以帮助到遇到同样问题的小伙伴
# invoke-webrequest 下载慢
其中有一个负责下载镜像和驱动的脚本文件,我是用了 iwr
来下载,但是在实际运行时发现下载不能跑满速,下载驱动和镜像需要花费一个多小时
老实说,我以前经常用 iwr
下载文件,并没有发现这个问题,是因为我以前用来下载的都是小文件,毕竟以前用这个命令比较多的地方还是无文件落地这方面,所以不会下载很大的文件
我开始怀疑是不是因为 iwr
命令的问题,但是后续我尝试了使用 wget
下载也一样慢
最后发现只需要将 $ProgressPreference
变量的默认值 Continue
更改成 SilentlyContinue
即可满速下载
本地测试一下更改前后的下载时间,下载一个 4G 左右的 win10 镜像,更改前用时 11 分钟
更改后,用时 18 秒
最终测试最优解是用 Start-BitsTransfer
命令下载大文件,下载速度要优于 iwr
,且不需要更改 $ProgressPreference
变量
按照微软文档的描述, $ProgressPreference
默认值为 Continue
时,脚本命令会在当前窗口生成一个进度栏,以描述运行中脚本状态
我不太明白如果仅仅是显示进度栏,应该不至于会导致下载速度变得如此之慢,具体的原因还是等以后自己有能力分析的时候再深入研究
# 在 32 位模式下运行 64 位应用
在安装完操作系统后,系统进入桌面后会自动调用安装驱动的脚本中,执行 pnputil
命令的时候返回 ObjectNotFound
, 即使我指定绝对路径也不行
# 指定备份驱动程序文件夹的路径 | |
$backupFolderPath = "c:\driver" | |
# 获取备份文件夹中所有的 INF 文件 | |
$infFiles = Get-ChildItem -Path $backupFolderPath -Filter "*.inf" -File -Recurse | |
# 遍历并安装每个 INF 文件 | |
foreach ($infFile in $infFiles) { | |
# 安装驱动程序 | |
pnputil.exe /add-driver $infFile.FullName /install | |
} |
经过测试发现,EPM 模板默认调用的是 32 位的 powershell
执行脚本,所以才导致无法执行 64 位的 pnputil
命令,即使我写一个计划任务脚本,将这个安装驱动的脚本添加到计划任务中执行,结果也依然一样
最终只能更改脚本内容,通过 %windir%\Sysnative
虚拟目录让 32 位的 powershell
执行 64 位的 powershell
再调用 pnputil
命令安装驱动
# 指定备份驱动程序文件夹的路径 | |
$backupFolderPath = "C:\driver\" | |
# 获取备份文件夹中所有的 INF 文件 | |
$infFiles = Get-ChildItem -Path $backupFolderPath -Filter "*.inf" -File -Recurse | |
# 构建要在 64 位 PowerShell 中运行的命令 | |
$commands = @() | |
foreach ($infFile in $infFiles) { | |
$commands += "pnputil.exe /add-driver `"$($infFile.FullName)`" /install" | |
} | |
# 将命令转换为字符串并以;进行分割 | |
$commandString = $commands -join "; " | |
# 创建一个临时脚本文件来存储命令 | |
$tempScriptPath = [System.IO.Path]::GetTempFileName() + ".ps1" | |
Set-Content -Path $tempScriptPath -Value $commandString | |
# 使用 64 位 PowerShell 执行临时脚本 | |
$sysNativePath = "$env:windir\Sysnative\WindowsPowerShell\v1.0\powershell.exe" | |
Start-Process -FilePath $sysNativePath -ArgumentList "-ExecutionPolicy Bypass -File `"$tempScriptPath`"" -Wait | |
# 删除临时脚本文件 | |
Remove-Item -Path $tempScriptPath |
参考文档: https://learn.microsoft.com/zh-cn/windows/win32/winprog64/file-system-redirector