给不会用电脑的人写一键脚本
妹妹今年上大学,买了台笔记本,激活完就卡住了:不会分盘,不知道装什么软件,也说不清楚哪里不对。
需求听上去很简单——切个 D 盘、建几个文件夹、装上微信 QQ WPS。做成一个双击就跑完的脚本,功能部分半小时能写完。真正花时间的是另一件事:这个脚本的使用者,没有能力处理它失败的情况。
这个约束一旦成立,很多平时无所谓的设计就变成了硬要求。
第一条:不确定就不要动
分区是不可逆的。而"新笔记本"这个前提,比想象中不可靠得多。
我一开始的版本直接读 C 盘大小、算个数、Resize-Partition 走起。写完就发现这条路上埋了至少四颗雷:
- 机器可能已经有 D 盘。品牌机预装两个分区的不少,再切一刀纯属添乱。
- 可能是双硬盘。SSD + 机械的机器,正确做法是把第二块盘做成 D,而不是切系统盘。
- D 这个盘符可能被光驱或 U 盘占着。新建分区会直接失败。
- C 盘可能已经加密。这颗雷最大,下面单独说。
所以最终版本的第一步不是分盘,是体检。上面四种情况命中任何一种,脚本都会跳过分盘、打印原因、继续做后面的事——而不是报个错就死在那里。
对一个不会排错的用户来说,"少做一件事"永远好过"做错一件事"。
分盘大小也不写死,按硬盘容量分档:512GB 的机器给 C 留 200GB,1TB 留 280GB,剩下的全给 D。算完先把方案打印出来,等一个明确的 Y。
第二条:家庭版没有你以为的那些命令
BitLocker 是这次最大的坑。
现在的品牌机预装 Win11 家庭版,激活时登录微软账号,系统会自动开启设备加密。用户完全无感,但加密状态下调整分区会直接失败。
我最初的检测是这么写的:
(Get-BitLockerVolume -MountPoint 'C:').ProtectionStatus -eq 'On'
看起来没毛病,实际上是错的:Get-BitLockerVolume 属于 BitLocker 模块,家庭版根本没有这个模块。
于是在目标机器上,这行代码不会报错说"加密了",它会报错说"找不到命令"。而我把它包在 -ErrorAction SilentlyContinue 里,结果就是静默失效——脚本以为没加密,兴冲冲跑去 resize,然后失败在一个更深、更难看的地方。
改成查 WMI 就好了,这个类家庭版有:
Get-CimInstance -Namespace 'root\CIMV2\Security\MicrosoftVolumeEncryption' `
-ClassName Win32_EncryptableVolume -Filter "DriveLetter='C:'"
教训不是"要查文档",而是:在你自己没有的运行环境上写代码,任何"应该有"的假设都要当成没有。
第三条:先搬文件,再改注册表
分盘只解决了一半问题。真正让 C 盘爆掉的,是"文档""下载""图片"这些默认位置全都在 C 盘——分完盘她照样把东西往 C 盘存,D 盘那三个文件夹会一直空着。
所以脚本还会把这几个系统文件夹重定向到 D:\个人文件\。这一步的顺序是有讲究的:
- 读出当前真实路径
- 判断能不能动
robocopy /MOVE把已有文件搬过去- 搬成功了,才改注册表
反过来写——先改注册表再搬文件——一旦中途失败,就会留下"注册表指向 D 盘、文件还在 C 盘"的分裂状态。系统会在 D 盘建个空文件夹,旧文件从此在资源管理器里消失,但磁盘占用一点没少。这是普通用户最没办法自己发现、也最没办法自己修的一种坏法。
按现在的顺序,最坏情况是原封不动。
这里还有第五颗雷:OneDrive。Win11 用微软账号登录时,OOBE 流程会推荐开启"文件夹备份",很多人顺手就点了。开了之后"文档"的真实路径已经变成 C:\Users\xxx\OneDrive\文档,这时候再往 D 盘重定向,会和 OneDrive 的同步逻辑打架。所以每个文件夹动手前都要看一眼路径里有没有 OneDrive,有就跳过并说明原因。
第四条:给它一个"只看不动"的模式
前面三条都是我在没有 Windows 环境的情况下推出来的——我写这个脚本的机器是台 Linux VPS,Resize-Partition 这些命令一行都执行不了。
这种情况下把脚本交给别人,是不负责任的。所以工具化的时候加的第一个功能是体检模式:
1 正式执行 分盘、建文件夹、改默认位置、装软件
2 只体检 打印它打算做什么,一个字节都不改
3 退出
选 2 的时候,脚本走完全部检测逻辑,把每一个即将发生的改动打印成一行 [体检] 将会:...,然后什么都不做。用户可以先看清楚,再决定要不要真跑。
为了确认这个模式真的是惰性的,我写了个测试台:把 Resize-Partition、New-Partition、robocopy、winget 这些会改动系统的调用全部替换成"绊线"函数——被调用就记一笔——然后在 Linux 上用假的磁盘数据把脚本完整跑一遍。
[体检] 将会:把 C 盘收缩到 280.0 GB,并用余下的 720.0 GB 新建 D 盘
[体检] 将会:创建文件夹 D:\娱乐
[体检] 将会:把「文档」从 C:\Users\mei\Documents 搬到 D:\个人文件\文档
图片 :目前由 OneDrive 接管,跳过。
[体检] 将会:用 winget 安装 微信(包名 Tencent.WeChat)
...
通过:体检模式全程未触发任何改动系统的调用
第一次跑的时候它显示"通过",但那是假的——我替换管理员检查的正则没匹配上,脚本在第 72 行就退出了,根本没执行到后面。一个从不运行的测试永远是绿的,这大概是这次最值得记住的一秒钟。
修好之后又补了第二个场景:已有 D 盘、且图片文件夹被 OneDrive 接管。两个场景合起来才把五个步骤全覆盖到。
最后一公里:SmartScreen
脚本写完了,打包挂到网上,链接发过去。她点开,然后卡在了一个蓝色的弹窗上。
"Windows 已保护你的电脑"——从网上下载的文件带 Mark-of-the-Web,双击 .bat 必然触发 SmartScreen。这个弹窗只有一个【确定】按钮,"更多信息 → 仍要运行"藏在左下角一行小字里。没见过的人会直接以为文件是坏的。
顺带一提,.bat 和 .ps1 千万别直接挂在网页上给人下——Edge 和 Chrome 会直接拦掉裸的 .bat,很多时候连"保留"都不给。打包成 zip 才能正常下载。
所以说明书的第 0 步不是"解压",是"Windows 会拦一下,这是正常的,点这里继续"。
这一条不是技术问题,但它和前面所有技术细节的重要性完全相同:用户走不到你的代码,你的代码写得再对也等于零。
拿去用
工具叫 firstboot,打包好了:
- 下载 firstboot v1.0.0(zip,约 10 KB)
- 校验和:firstboot-1.0.0.zip.sha256
软件列表和文件夹名都在 setup.ps1 开头的配置区,想换成别的自己改。默认装的是微信、QQ、腾讯会议、腾讯视频、WPS——大学生装机的最大公约数。
它已经在一台全新的华硕无畏16 上跑通了。但你的机器不是那台机器,第一次用请先选 2。