Compare commits

...

19 Commits

Author SHA1 Message Date
87301108df windows: 更准确地识别镜像系统版本 2026-05-20 21:25:30 +08:00
8d099f167f core: 修复原系统为 bios + nixos 重启后未能进入安装环境 2026-05-20 21:15:43 +08:00
37af3fcd5f nixos: 配置安装时 substituters (#619) 2026-05-20 21:05:39 +08:00
9e71f131db opensuse: 删除 leap 15.6 和 wicked 2026-05-11 20:20:33 +08:00
e03ac1cdb3 core: 必要时才修改 ssh 配置 2026-05-11 20:18:44 +08:00
65c3085416 windows: 使用 ProductType 判断 Windows Client/Server 2026-05-09 22:04:24 +08:00
139c342b7e windows: 支持使用非 administrator 账号 2026-05-05 22:55:00 +08:00
107c56ac59 windows: 修复无法从法语版 win7 wmic 取出主硬盘 id 2026-05-05 22:35:47 +08:00
2f36c30a7d gentoo: 修复安装 dracut 时报错 2026-05-05 22:35:47 +08:00
7712a0baae windows: 国内机下载驱动出错后使用 daocloud 镜像 2026-05-04 02:57:08 +08:00
c5c77b2ecc core: efibootmgr 报错时显示执行的命令和结果 2026-05-03 23:08:03 +08:00
0156afbbe7 fedora: 安装时使用 mount -a 挂载分区和子卷
fedora: 添加 44
2026-04-30 22:08:15 +08:00
047b82aaa0 core: 用于引导参数时不需要判断 tty 是否存在和可写 2026-04-28 07:33:09 +08:00
0db534c4fd core: 不重要的优化 2026-04-28 07:33:09 +08:00
07b46d78b0 windows: 删除 ProtectYourPC 设置,使首次登录可自定义隐私选项 2026-04-28 07:33:09 +08:00
0b1a0d2f69 windows: 优化安装流程 2026-04-28 07:33:08 +08:00
c3a5fff760 core: 优化 powershell 查询
- 避免 wmic where 条件有空格时报错
- 减少 ForEach-Object 以提高速度
2026-04-28 07:33:08 +08:00
4bb20b81eb windows: 国内服务器访问 intel.cn 2026-04-28 07:33:08 +08:00
86d6976d96 core: 添加 pci-hyperv / vpci.sys 驱动
修复 Azure 安装 debian / windows 10 ltsc 时不到 nvme 硬盘
2026-04-28 07:33:07 +08:00
12 changed files with 863 additions and 419 deletions

View File

@ -37,7 +37,7 @@ jobs:
${{ matrix.command }} netboot.xyz ${{ matrix.command }} netboot.xyz
${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz ${{ matrix.command }} dd --img=https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-SelfInstall.raw.xz
${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage ${{ matrix.command }} windows --image-name='Windows Server blah' --iso https://aka.ms/HCIReleaseImage --username administrator
${{ matrix.command }} reset ${{ matrix.command }} reset

View File

@ -56,9 +56,9 @@ The system requirements for the target system are as follows:
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 43, 44 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (Rolling) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 16.0, Tumbleweed (Rolling) | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | Rolling | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | Rolling | 512 MB | 5 GB |
@ -149,7 +149,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
- Username `root`. The script prompts for a password. If left blank, a random one is generated. - Username `root`. The script prompts for a password. If left blank, a random one is generated.
- When installing the latest version, the version number does not need to be specified. - When installing the latest version, the version number does not need to be specified.
- Maximizes disk space usage: no boot partition (except for Fedora) and no swap partition. - Maximizes disk space utilization: no boot or swap partitions.
- Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels. - Automatically selects different optimized kernels based on machine type, such as `Cloud` or `HWE` kernels.
- When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install `qcow2` of other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`. - When installing Red Hat, you must provide the `qcow2` image link obtained from <https://access.redhat.com/downloads/content/rhel>. You can also install `qcow2` of other RHEL-based OS, such as `Alibaba Cloud Linux` and `TencentOS Server`.
- After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`. - After reinstallation, if you need to change the SSH port or switch to key-based login, make sure to also modify the files inside `/etc/ssh/sshd_config.d/`.
@ -163,11 +163,11 @@ bash reinstall.sh anolis 7|8|23
centos 9|10 centos 9|10
fnos 1 fnos 1
nixos 25.11 nixos 25.11
fedora 42|43 fedora 43|44
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 16.0|tumbleweed
openeuler 20.03|22.03|24.03
alpine 3.20|3.21|3.22|3.23 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09
ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal] ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal]
kali kali
arch arch
@ -327,11 +327,12 @@ bash reinstall.sh netboot.xyz
> >
> If the script was run by mistake, you can run `bash reinstall.sh reset` before rebooting to cancel the reinstallation operation. > If the script was run by mistake, you can run `bash reinstall.sh reset` before rebooting to cancel the reinstallation operation.
- Username `administrator`. The script prompts for a password. If left blank, a random one is generated. - The script prompts for a username. If left blank, will use `administrator`.
- If remote login fails, try using the username `.\administrator`. - The script prompts for a password. If left blank, will use a random one.
- If remote login fails, try adding `.\` before the username, for example, `.\administrator`.
- The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot. - The machine with a static IP will automatically configure the IP. It may take a few minutes to take effect on the first boot.
- Supports ISO images in any language. - Supports ISO images in any language.
- Supports bypassing Windows 11 hardware requirements. - Automatically bypassing Windows 11 hardware requirements.
#### Supported Systems #### Supported Systems
@ -446,6 +447,7 @@ bash reinstall.sh windows \
#### Optional Parameters #### Optional Parameters
- `--username USERNAME` Set Username (for Windows only)
- `--password PASSWORD` Set Password - `--password PASSWORD` Set Password
- `--allow-ping` Configure Windows Firewall to Allow Ping Responses - `--allow-ping` Configure Windows Firewall to Allow Ping Responses
- `--rdp-port PORT` Change RDP port - `--rdp-port PORT` Change RDP port
@ -582,12 +584,14 @@ bash reinstall.sh reset
According to the Law of Bug Conservation, fixing old bugs often introduces new ones. According to the Law of Bug Conservation, fixing old bugs often introduces new ones.
If a new bug occurs, try using an older version to see if it works. If a bug occurs, try using an older version to see if it works.
Go to <https://github.com/bin456789/reinstall/commits/main> and find the old versions `commit_id` on the right side. Go to <https://github.com/bin456789/reinstall/commits/main> and find the old versions `commit_id` on the right side.
Replace `xxxxxxxx` in the script below with the `commit_id` of an older version and run the script.
```bash ```bash
commit_id=xxxxxxx commit_id=xxxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_ curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ... bash reinstall.sh ...
@ -598,6 +602,7 @@ bash reinstall.sh ...
1. Fork this repository. 1. Fork this repository.
2. Modify the `confhome` and `confhome_cn` at the beginning of `reinstall.sh` and `reinstall.bat`. 2. Modify the `confhome` and `confhome_cn` at the beginning of `reinstall.sh` and `reinstall.bat`.
3. Make changes to the other code. 3. Make changes to the other code.
4. Download and run your `reinstall.sh` or `reinstall.bat`."
## Thanks ## Thanks

View File

@ -56,9 +56,9 @@
| <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.redhat.com/favicon.ico" /> RHEL &nbsp;<img width="16" height="16" src="https://almalinux.org/fav/favicon.ico" /> AlmaLinux &nbsp;<img width="16" height="16" src="https://rockylinux.org/favicon.png" /> Rocky &nbsp;<img width="16" height="16" src="https://www.oracle.com/asset/web/favicons/favicon-32.png" /> Oracle | 8, 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://opencloudos.org/qq.ico" /> OpenCloudOS | 8, 9, Stream 23 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.centos.org/assets/icons/favicon.svg" /> CentOS Stream | 9, 10 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://fedoraproject.org/favicon.ico" /> Fedora | 43, 44 | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS, 25.09 | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://www.openeuler.org/favicon.ico" /> openEuler | 20.03 LTS - 24.03 LTS | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (滚动) | 512 MB \* | 5 GB | | <img width="16" height="16" src="https://static.opensuse.org/favicon.ico" /> openSUSE | Leap 16.0, Tumbleweed (滚动) | 512 MB \* | 5 GB |
| <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB | | <img width="16" height="16" src="https://nixos.org/favicon.svg" /> NixOS | 25.11 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB | | <img width="16" height="16" src="https://archlinux.org/static/favicon.png" /> Arch | 滚动 | 512 MB | 5 GB |
| <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB | | <img width="16" height="16" src="https://www.gentoo.org/assets/img/logo/gentoo-g.png" /> Gentoo | 滚动 | 512 MB | 5 GB |
@ -149,7 +149,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
- 用户名为 `root`,脚本会提示输入密码,不输入则使用随机密码 - 用户名为 `root`,脚本会提示输入密码,不输入则使用随机密码
- 安装最新版可不输入版本号 - 安装最新版可不输入版本号
- 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区 - 最大化利用磁盘空间:不含 boot swap 分区
- 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核 - 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统的 `qcow2`,例如 `Alibaba Cloud Linux``TencentOS Server` - 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统的 `qcow2`,例如 `Alibaba Cloud Linux``TencentOS Server`
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件 - 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
@ -163,11 +163,11 @@ bash reinstall.sh anolis 7|8|23
centos 9|10 centos 9|10
fnos 1 fnos 1
nixos 25.11 nixos 25.11
fedora 42|43 fedora 43|44
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 16.0|tumbleweed
openeuler 20.03|22.03|24.03
alpine 3.20|3.21|3.22|3.23 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09
ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal] ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal]
kali kali
arch arch
@ -327,11 +327,12 @@ bash reinstall.sh netboot.xyz
> >
> 如果不小心运行了脚本,可以在重启前运行 `bash reinstall.sh reset` 取消重装 > 如果不小心运行了脚本,可以在重启前运行 `bash reinstall.sh reset` 取消重装
-户名为 `administrator`,脚本会提示输入密码,不输入则使用随机密码 - 脚本会提示输入用户名,不输入则使`administrator`
- 如果远程登录失败,可以尝试使用用户名 `.\administrator` - 脚本会提示输入密码,不输入则使用随机密码
- 如果远程登录失败,请尝试在用户名前添加 `.\`,例如 `.\administrator`
- 静态机器会自动配置好 IP可能首次开机几分钟后才生效 - 静态机器会自动配置好 IP可能首次开机几分钟后才生效
- 支持任意语言的 ISO - 支持任意语言的 ISO
- 支持绕过 Windows 11 硬件限制 - 自动绕过 Windows 11 硬件限制
#### 支持的系统 #### 支持的系统
@ -446,6 +447,7 @@ bash reinstall.sh windows \
#### 可选参数 #### 可选参数
- `--username USERNAME` 设置用户名(仅限 Windows
- `--password PASSWORD` 设置密码 - `--password PASSWORD` 设置密码
- `--allow-ping` 设置 Windows 防火墙允许被 Ping - `--allow-ping` 设置 Windows 防火墙允许被 Ping
- `--rdp-port PORT` 更改 RDP 端口 - `--rdp-port PORT` 更改 RDP 端口
@ -582,12 +584,14 @@ bash reinstall.sh reset
根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug 根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug
如果遇到新的 Bug,可以试下旧版本是否正常 如果脚本出现问题,可以试下旧版本是否正常
<https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id` <https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id`
将下面脚本的 `xxxxxxxx` 替换成旧版本的 `commit_id` 并运行脚本
```bash ```bash
commit_id=xxxxxxx commit_id=xxxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_ curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ... bash reinstall.sh ...
@ -598,6 +602,7 @@ bash reinstall.sh ...
1. Fork 本仓库 1. Fork 本仓库
2. 修改 `reinstall.sh``reinstall.bat` 开头的 `confhome``confhome_cn` 2. 修改 `reinstall.sh``reinstall.bat` 开头的 `confhome``confhome_cn`
3. 修改其它代码 3. 修改其它代码
4. 下载并运行你的 `reinstall.sh``reinstall.bat`
## 感谢 ## 感谢

View File

@ -170,47 +170,6 @@ GatewayOnLink=yes
fi fi
} }
fix_wicked_conf() {
# https://github.com/openSUSE/wicked/wiki/FAQ#q-why-wicked-does-not-set-my-default-static-route
# 修改前
# default 1.1.1.1 - -
# default 2602::1 - -
# 修改后
# 1.1.1.1 - -
# 2602::1 - -
# default 1.1.1.1 - -
# default 2602::1 - -
if ! confs=$(ls "$os_dir/etc/sysconfig/network/ifroute-"* 2>/dev/null); then
return
fi
for conf in $confs; do
# 判断 bug 是否已经修复
if grep -v 'default' "$conf" | grep -q '-'; then
return
fi
# 获取网关
gateways=$(awk '$1=="default" {print $2}' "$conf")
if [ -z "$gateways" ]; then
return
fi
# 创建新条目
for gateway in $gateways; do
echo "$gateway - -"
done | insert_into_file "$conf" head
done
# 重新应用配置
if systemctl -q is-enabled wicked; then
systemctl restart wicked
fi
}
# ubuntu 18.04 cloud-init 版本 23.1.2,因此不用处理 # ubuntu 18.04 cloud-init 版本 23.1.2,因此不用处理
# debian 10/11 云镜像原本用 ifupdown + resolvconf脚本改成用 netplan + networkd/resolved # debian 10/11 云镜像原本用 ifupdown + resolvconf脚本改成用 netplan + networkd/resolved
@ -224,6 +183,3 @@ fix_netplan_conf
# 只需对云镜像处理 # 只需对云镜像处理
# 因为普通安装用的是 alpine 的 cloud-init版本够新不用处理 # 因为普通安装用的是 alpine 的 cloud-init版本够新不用处理
fix_networkd_conf fix_networkd_conf
# opensuse 15.5: ifcfg + netconfig (dns) + wicked
fix_wicked_conf

View File

@ -9,10 +9,6 @@ Before=network.service
Before=networking.service Before=networking.service
Before=systemd-networkd.service Before=systemd-networkd.service
Before=NetworkManager.service Before=NetworkManager.service
Before=wickedd-auto4.service
Before=wickedd-dhcp4.service
Before=wickedd-dhcp6.service
Before=wickedd.service
Before=network.target Before=network.target

View File

@ -84,11 +84,11 @@ Usage: $reinstall_____ anolis 7|8|23
centos 9|10 centos 9|10
fnos 1 fnos 1
nixos 25.11 nixos 25.11
fedora 42|43 fedora 43|44
debian 9|10|11|12|13 debian 9|10|11|12|13
opensuse 16.0|tumbleweed
openeuler 20.03|22.03|24.03
alpine 3.20|3.21|3.22|3.23 alpine 3.20|3.21|3.22|3.23
opensuse 15.6|16.0|tumbleweed
openeuler 20.03|22.03|24.03|25.09
ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal] ubuntu 18.04|20.04|22.04|24.04|26.04 [--minimal]
kali kali
arch arch
@ -643,13 +643,12 @@ wmic() {
curl -Lo "$tmp/wmic.ps1" "$confhome/wmic.ps1" curl -Lo "$tmp/wmic.ps1" "$confhome/wmic.ps1"
fi fi
# shellcheck disable=SC2046
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass \ powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass \
-File "$(cygpath -w "$tmp/wmic.ps1")" \ -File "$(cygpath -w "$tmp/wmic.ps1")" \
-Namespace "$namespace" \ -Namespace "$namespace" \
-Class "$class" \ -Class "$class" \
$([ -n "$filter" ] && echo -Filter "$filter") \ ${filter:+"-Filter"} ${filter:+"$filter"} \
$([ -n "$props" ] && echo -Properties "$props") ${props:+"-Properties"} ${props:+"$props"}
} }
is_virt() { is_virt() {
@ -703,12 +702,6 @@ is_virt() {
$_is_virt $_is_virt
} }
is_absolute_path() {
# 检查路径是否以/开头
# 注意语法和 ash 不同
[[ "$1" = /* ]]
}
is_cpu_supports_x86_64_v3() { is_cpu_supports_x86_64_v3() {
# 用 ld.so/cpuid/coreinfo.exe 更准确 # 用 ld.so/cpuid/coreinfo.exe 更准确
# centos 7 /usr/lib64/ld-linux-x86-64.so.2 没有 --help # centos 7 /usr/lib64/ld-linux-x86-64.so.2 没有 --help
@ -1486,13 +1479,11 @@ Continue?
# leap # leap
dir=distribution/leap/$releasever/appliances dir=distribution/leap/$releasever/appliances
case "$releasever" in case "$releasever" in
15.6) file=openSUSE-Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;; 16.0) file=Leap-$releasever-Minimal-VM.$basearch-Cloud.qcow2 ;;
# 16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;; # 16.0) file=Leap-$releasever-Minimal-VM.$basearch-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
esac esac
# https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi # https://src.opensuse.org/openSUSE/Leap-Images/src/branch/leap-16.0/kiwi-templates-Minimal/Minimal.kiwi
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Leap-15.6/packages/kiwi-templates-Minimal/files/Minimal.kiwi
# https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Tumbleweed/packages/kiwi-templates-Minimal/files/Minimal.kiwi # https://build.opensuse.org/projects/Virtualization:Appliances:Images:openSUSE-Tumbleweed/packages/kiwi-templates-Minimal/files/Minimal.kiwi
# 有专门的kvm镜像openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2里面没有cloud-init # 有专门的kvm镜像openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2里面没有cloud-init
# file=openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2 # file=openSUSE-Leap-15.5-Minimal-VM.x86_64-kvm-and-xen.qcow2
@ -1917,12 +1908,12 @@ verify_os_name() {
'rocky 8|9|10' \ 'rocky 8|9|10' \
'oracle 8|9|10' \ 'oracle 8|9|10' \
'fnos 1' \ 'fnos 1' \
'fedora 42|43' \ 'fedora 43|44' \
'nixos 25.11' \ 'nixos 25.11' \
'debian 9|10|11|12|13' \ 'debian 9|10|11|12|13' \
'opensuse 15.6|16.0|tumbleweed' \ 'opensuse 16.0|tumbleweed' \
'alpine 3.20|3.21|3.22|3.23' \ 'alpine 3.20|3.21|3.22|3.23' \
'openeuler 20.03|22.03|24.03|25.09' \ 'openeuler 20.03|22.03|24.03' \
'ubuntu 18.04|20.04|22.04|24.04|26.04' \ 'ubuntu 18.04|20.04|22.04|24.04|26.04' \
'redhat' \ 'redhat' \
'kali' \ 'kali' \
@ -2349,6 +2340,59 @@ trim() {
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
} }
assert_username_valid() {
if ! msg=$(is_username_valid); then
error_and_exit "$msg"
fi
}
is_username_valid() {
# https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-localaccounts-localaccount-name
# 不能为 none [ ] / \ : | < > + = ; , ? * % @
# 账号为空,则使用 Administrator
if [ -z "$username" ]; then
echo "Username: Will use the built-in Administrator account in ISO language."
return 0
fi
if [ "$(to_lower <<<"$username")" = none ]; then
echo "Username: Do not use the name \"NONE\", this is a restricted username."
return 1
fi
if grep -q '[][/\:|<>+=;,?*%@]' <<<"$username"; then
echo "Username: Do not use any of the following characters: / \ [ ] : | < > + = ; , ? * % @"
return 1
fi
# 如果输入以下用户名则忽略,并使用系统内置的 Administrator 账号
# 防止系统有两个不同语言的 Administrator 账号而造成困扰
for builtin_username in \
administrator \
administrador \
administrateur \
administratör \
администратор \
järjestelmänvalvoja \
rendszergazda; do
if [ "$(to_lower <<<"$username")" = "$builtin_username" ]; then
echo "Username: Will use the built-in Administrator account in ISO language."
unset username
return 0
fi
done
}
prompt_username() {
info "prompt username"
warn false "Leave blank to use Administrator"
warn false "不填写则使用 Administrator"
IFS= read -r -p "Username: " username
username="$(printf "%s" "$username" | trim)"
assert_username_valid
}
prompt_password() { prompt_password() {
info "prompt password" info "prompt password"
warn false "Leave blank to use a random password." warn false "Leave blank to use a random password."
@ -2888,18 +2932,20 @@ add_efi_entry_in_linux() {
dev_part=$(findmnt -T "$dist_dir" -no SOURCE | grep '^/dev/') dev_part=$(findmnt -T "$dist_dir" -no SOURCE | grep '^/dev/')
fi fi
if ! { set -- efibootmgr --create-only \
res=$(efibootmgr --create-only \ --disk "/dev/$(get_disk_by_part $dev_part)" \
--disk "/dev/$(get_disk_by_part $dev_part)" \ --part "$(get_part_num_by_part $dev_part)" \
--part "$(get_part_num_by_part $dev_part)" \ --label "$(get_entry_name)" \
--label "$(get_entry_name)" \ --loader "\\EFI\\reinstall\\$basename"
--loader "\\EFI\\reinstall\\$basename") &&
id=$(echo "$res" | grep_efi_entry | tail -1 | grep_efi_index | grep .) && if ! res=$("$@"); then
efibootmgr --bootnext "$id" echo "Command: $*"
}; then
echo "$res" echo "$res"
error_and_exit "Could not add efi entry." error_and_exit "Could not add efi entry."
fi fi
id=$(echo "$res" | grep_efi_entry | tail -1 | grep_efi_index | grep .)
efibootmgr --bootnext "$id"
} }
get_grub_efi_filename() { get_grub_efi_filename() {
@ -3123,7 +3169,7 @@ build_extra_cmdline() {
# https://salsa.debian.org/installer-team/rootskel/-/blob/master/src/lib/debian-installer-startup.d/S02module-params?ref_type=heads # https://salsa.debian.org/installer-team/rootskel/-/blob/master/src/lib/debian-installer-startup.d/S02module-params?ref_type=heads
for key in confhome hold force_boot_mode force_cn force_old_windows_setup cloud_image main_disk \ for key in confhome hold force_boot_mode force_cn force_old_windows_setup cloud_image main_disk \
elts deb_mirror \ elts deb_mirror \
ssh_port rdp_port web_port allow_ping; do username ssh_port rdp_port web_port allow_ping; do
value=${!key} value=${!key}
if [ -n "$value" ]; then if [ -n "$value" ]; then
is_need_quote "$value" && is_need_quote "$value" &&
@ -3230,7 +3276,7 @@ build_cmdline() {
# 脚本可能多次运行,先清理之前的残留 # 脚本可能多次运行,先清理之前的残留
mkdir_clear() { mkdir_clear() {
dir=$1 local dir=$1
if [ -z "$dir" ] || [ "$dir" = / ]; then if [ -z "$dir" ] || [ "$dir" = / ]; then
return return
@ -3411,6 +3457,32 @@ EOF
fi fi
} }
cp_debian_kali_driver() {
# debian 13 的 linux-image.deb 有 /usr/lib 没有 /lib
# debian 13 的 scsi-modules.udeb 没有 /usr/lib 有 /lib
local src_drivers_dir=$1/lib/modules/$kver/kernel/drivers
if ! [ -d "$src_drivers_dir" ]; then
local src_drivers_dir=$1/usr/lib/modules/$kver/kernel/drivers
fi
local extra_drivers=$2
# 各个版本的 debian/kali installer initrd 都有 /lib
local dst_drivers_dir=$initrd_dir/lib/modules/$kver/kernel/drivers
(
cd $src_drivers_dir
for driver in $extra_drivers; do
# debian 模块没有压缩
# kali 模块有压缩
# 因此要有 *
if ! find $dst_drivers_dir -name "$driver.ko*" | grep -q .; then
echo "adding driver: $driver"
file=$(find . -name "$driver.ko*" | grep .)
cp -fv --parents "$file" "$dst_drivers_dir"
fi
done
)
}
# 不用在 windows 判断是哪种硬盘控制器,因为 256M 运行 windows 只可能是 xp而脚本本来就不支持 xp # 不用在 windows 判断是哪种硬盘控制器,因为 256M 运行 windows 只可能是 xp而脚本本来就不支持 xp
# 在 debian installer 中判断能否用云内核 # 在 debian installer 中判断能否用云内核
create_can_use_cloud_kernel_sh can_use_cloud_kernel.sh create_can_use_cloud_kernel_sh can_use_cloud_kernel.sh
@ -3471,6 +3543,24 @@ EOF
cp -f $tmp/websocketd/usr/bin/websocketd usr/bin/ cp -f $tmp/websocketd/usr/bin/websocketd usr/bin/
fi fi
# 提前下载 pci-hyperv
# udeb 没有这个模块 curl https://deb.debian.org/debian/dists/stable/main/Contents-udeb-amd64.gz | zcat | grep pci-hyperv
# 缺少这个模块 azure 会找不到 nvme 硬盘
# kali 的 pci-hyperv/pci-hyperv-intf 已嵌入到内核,不需要下载
# 用到 pci-hyperv 才需要下载,因为
# 1. azure 普通网卡、scsi 硬盘不需要这个模块
# 2. 没有这个模块会缺少加速网卡,但还有 hyperv 合成网卡,可以正常上网
if { is_in_windows && wmic PATH Win32_PnPEntity where "DeviceID like 'VMBUS\\\\{44C4F61D-4444-4400-9D52-802E27EDE19F}\\\\%'" | grep -q . ||
[ -d /sys/module/pci_hyperv ]; } &&
# 可能在 host 或 controller 文件夹
! ls lib/modules/$kver/kernel/drivers/pci/*/pci-hyperv.ko* >/dev/null 2>&1 &&
! grep -Fq /pci-hyperv.ko lib/modules/$kver/modules.builtin; then
mkdir_clear $tmp/linux-image-$kver
download_and_extract_deb deb linux-image-$kver $tmp/linux-image-$kver
cp_debian_kali_driver $tmp/linux-image-$kver pci-hyperv
fi
# >256M 或者当前系统是 windows # >256M 或者当前系统是 windows
if [ $ram_size -gt 256 ] || is_in_windows; then if [ $ram_size -gt 256 ] || is_in_windows; then
sed -i '/^pata-modules/d' $net_retriever sed -i '/^pata-modules/d' $net_retriever
@ -3505,27 +3595,11 @@ EOF
# xen 还需要以下两个? # xen 还需要以下两个?
# kernel/drivers/xen/xen-scsiback.ko # kernel/drivers/xen/xen-scsiback.ko
# kernel/drivers/block/xen-blkback/xen-blkback.ko # kernel/drivers/block/xen-blkback/xen-blkback.ko
# 但反查也找不到 curl https://deb.debian.org/debian/dists/bookworm/main/Contents-udeb-amd64.gz | zcat | grep xen # udeb 没有这个模块 curl https://deb.debian.org/debian/dists/stable/main/Contents-udeb-amd64.gz | zcat | grep xen
if [ -n "$extra_drivers" ]; then if [ -n "$extra_drivers" ]; then
mkdir_clear $tmp/scsi mkdir_clear $tmp/scsi
download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi
relative_drivers_dir=lib/modules/$kver/kernel/drivers cp_debian_kali_driver $tmp/scsi "$extra_drivers"
udeb_drivers_dir=$tmp/scsi/$relative_drivers_dir
dist_drivers_dir=$initrd_dir/$relative_drivers_dir
(
cd $udeb_drivers_dir
for driver in $extra_drivers; do
# debian 模块没有压缩
# kali 模块有压缩
# 因此要有 *
if ! find $dist_drivers_dir -name "$driver.ko*" | grep -q .; then
echo "adding driver: $driver"
file=$(find . -name "$driver.ko*" | grep .)
cp -fv --parents "$file" "$dist_drivers_dir"
fi
done
)
fi fi
fi fi
@ -3580,6 +3654,7 @@ get_net_drivers() {
# 不用在 windows 判断是哪种硬盘/网络驱动,因为 256M 运行 windows 只可能是 xp而脚本本来就不支持 xp # 不用在 windows 判断是哪种硬盘/网络驱动,因为 256M 运行 windows 只可能是 xp而脚本本来就不支持 xp
# 而且安装过程也有二次判断 # 而且安装过程也有二次判断
# trans.sh 有同名方法
get_drivers() { get_drivers() {
# 有以下结果组合出现 # 有以下结果组合出现
# sd_mod # sd_mod
@ -3590,6 +3665,7 @@ get_drivers() {
# xen_blkfront # xen_blkfront
# ahci # ahci
# nvme # nvme
# pci_hyperv
# mptspi # mptspi
# mptsas # mptsas
# vmw_pvscsi # vmw_pvscsi
@ -3863,6 +3939,7 @@ This script is outdated, please download reinstall.sh again.
if [ "$hold" = 0 ]; then if [ "$hold" = 0 ]; then
info 'hold 0' info 'hold 0'
echo "Edit $tmp if needed."
read -r -p 'Press Enter to continue...' read -r -p 'Press Enter to continue...'
fi fi
@ -4117,7 +4194,7 @@ recreate_grub_or_extlinux_cfg() {
/nix/var/nix/profiles/system/bin/switch-to-configuration boot /nix/var/nix/profiles/system/bin/switch-to-configuration boot
# 手动启用 41_custom # 手动启用 41_custom
nixos_grub_home="$(dirname "$(readlink -f "$(get_cmd_path grub-mkconfig)")")/.." nixos_grub_home="$(dirname "$(readlink -f "$(get_cmd_path grub-mkconfig)")")/.."
$nixos_grub_home/etc/grub.d/41_custom >>$target_cfg $nixos_grub_home/etc/grub.d/41_custom >>"$(dirname "$target_cfg")/grub.cfg"
elif is_have_cmd update-grub; then elif is_have_cmd update-grub; then
update-grub update-grub
else else
@ -4286,6 +4363,7 @@ for o in ci installer debug minimal allow-ping force-cn help \
img: \ img: \
cloud-data: \ cloud-data: \
lang: \ lang: \
user: username: \
passwd: password: \ passwd: password: \
ssh-port: \ ssh-port: \
ssh-key: public-key: \ ssh-key: public-key: \
@ -4420,6 +4498,14 @@ while true; do
force_boot_mode=$2 force_boot_mode=$2
shift 2 shift 2
;; ;;
--user | --username)
if ! [ "$distro" = windows ]; then
error_and_exit "$1 is only supported for installing Windows."
fi
username="$(printf "%s" "$2" | trim)"
assert_username_valid
shift 2
;;
--passwd | --password) --passwd | --password)
[ -n "$2" ] || error_and_exit "Need value for $1" [ -n "$2" ] || error_and_exit "Need value for $1"
password=$2 password=$2
@ -4595,6 +4681,11 @@ done
# 检查必须的参数 # 检查必须的参数
verify_os_args verify_os_args
# 用户名
if [ "$distro" = windows ] && [ -z "$username" ]; then
prompt_username
fi
# 密码 # 密码
if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then
if is_use_dd; then if is_use_dd; then
@ -4874,7 +4965,7 @@ info 'info'
echo "$distro $releasever" echo "$distro $releasever"
case "$distro" in case "$distro" in
windows) username=administrator ;; windows) username=${username:-administrator} ;;
netboot.xyz) username= ;; netboot.xyz) username= ;;
dd | *) username=root ;; dd | *) username=root ;;
esac esac

703
trans.sh

File diff suppressed because it is too large Load Diff

16
ttys.sh
View File

@ -7,16 +7,24 @@ prefix=$1
# 注意 debian initrd 没有 xargs # 注意 debian initrd 没有 xargs
# 最后一个 tty 是主 tty显示的信息最全 # 最后一个 tty 是主 tty显示的信息最全
is_first=true
if [ "$(uname -m)" = "aarch64" ]; then if [ "$(uname -m)" = "aarch64" ]; then
ttys="ttyS0 ttyAMA0 tty0" ttys="ttyS0 ttyAMA0 tty0"
else else
ttys="ttyS0 tty0" ttys="ttyS0 tty0"
fi fi
# 安装环境下 tty 不一定齐全
# hytron 有ttyS0 但无法写入
# 用于 cmdline 引导参数时不需要判断 tty 是否存在和可写
if [ "$prefix" = "console=" ]; then
is_for_cmdline=true
else
is_for_cmdline=false
fi
is_first=true
for tty in $ttys; do for tty in $ttys; do
# hytron 有ttyS0 但无法写入 if $is_for_cmdline || stty -g -F "/dev/$tty" >/dev/null 2>&1; then
if stty -g -F "/dev/$tty" >/dev/null 2>&1; then
if $is_first; then if $is_first; then
is_first=false is_first=false
else else
@ -25,7 +33,7 @@ for tty in $ttys; do
printf "%s" "$prefix$tty" printf "%s" "$prefix$tty"
if [ "$prefix" = "console=" ] && if $is_for_cmdline &&
{ [ "$tty" = ttyS0 ] || [ "$tty" = ttyAMA0 ]; }; then { [ "$tty" = ttyS0 ] || [ "$tty" = ttyAMA0 ]; }; then
printf ",115200n8" printf ",115200n8"
fi fi

View File

@ -1,6 +1,6 @@
#!/bin/ash #!/bin/ash
# shellcheck shell=dash # shellcheck shell=dash
# shellcheck disable=SC3001,SC3003,SC3010 # shellcheck disable=SC3001,SC3003,SC3010,SC3015
# reinstall.sh / trans.sh 共用此文件 # reinstall.sh / trans.sh 共用此文件
# grep 无法处理 UTF-16LE 编码的 inf有以下几种解决方法 # grep 无法处理 UTF-16LE 编码的 inf有以下几种解决方法
@ -239,6 +239,27 @@ list_files_from_inf() {
done < <(echo "$inf_txts") done < <(echo "$inf_txts")
} }
is_x_starts_with_y() {
[[ "$1" =~ ^"$2" ]]
}
is_x_ends_with_y() {
[[ "$1" =~ "$2"$ ]]
}
is_absolute_path() {
# 检查路径是否以/开头
# alpine ash 可用
# [[ "$1" = "/*" ]]
# bash 可用
# [[ "$1" = /* ]]
# 都可用
is_x_starts_with_y "$1" /
}
# windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动 # windows 安装驱动时,只会安装相同架构的驱动文件到系统,即使 inf 里有列出其它架构的驱动
# 因此 DISM 导出驱动时,也就没有包含其它架构的驱动文件 # 因此 DISM 导出驱动时,也就没有包含其它架构的驱动文件
@ -284,7 +305,11 @@ get_path_in_correct_case() {
output="$output$part/" output="$output$part/"
else else
# 最后 part # 最后 part
output="$output$part" if is_x_ends_with_y "$path" /; then
output="$output$part/"
else
output="$output$part"
fi
fi fi
shift shift
done done

View File

@ -49,29 +49,22 @@ if exist X:\custom_drivers\ (
rem 等待加载分区 rem 等待加载分区
call :sleep 5000 call :sleep 5000
echo rescan | diskpart echo rescan | diskpart
call :sleep 5000
rem 判断 efi 还是 bios
rem 或者用 https://learn.microsoft.com/windows-hardware/manufacture/desktop/boot-to-uefi-mode-or-legacy-bios-mode
rem pe 下没有 mountvol
echo list vol | diskpart | find "efi" && (
set BootType=efi
) || (
set BootType=bios
)
rem 获取 ProductType rem 获取 ProductType
rem for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType') do ( rem for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType') do (
rem set "ProductType=%%a" rem set "ProductType=%%a"
rem ) rem )
rem 获取 BuildNumber rem 获取 installer 卷 id
for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do ( for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find " installer "') do (
set "BuildNumber=%%a" set "VolIndex=%%a"
) )
rem 获取 installer 卷 id rem 及时退出
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do ( if "%VolIndex%"=="" (
set "VolIndex=%%a" echo Error: Cannot find installer partition. >&2
exit /b 1
) )
rem 将 installer 分区设为 Y 盘 rem 将 installer 分区设为 Y 盘
@ -87,11 +80,63 @@ rem wmic pagefile
rem 获取主硬盘 id rem 获取主硬盘 id
rem vista pe 没有 wmic因此用 diskpart rem vista pe 没有 wmic因此用 diskpart
(echo select vol %VolIndex% & echo list disk) | diskpart | find "* Disk " > X:\disk.txt
for /f "tokens=3" %%a in (X:\disk.txt) do ( rem 法语版 win7 diskpart 始终输出法语,即使设置了 chcp 437因此不能用这个方法
set "DiskIndex=%%a" rem (echo select vol %VolIndex% & echo list disk) | diskpart | find "* Disk " > X:\disk.txt
rem for /f "tokens=3" %%a in (X:\disk.txt) do (
rem set "DiskIndex=%%a"
rem )
rem PE 下没有 findstr因此不能从 wmic 的输出直接选出开头为 * 的行,要用复杂的方法取出磁盘编号
rem 输出 diskpart 结果到文件
(echo select vol %VolIndex% & echo list disk) | diskpart | find "* " > X:\disk.txt
type X:\disk.txt
rem 逐行读取文件
setlocal enabledelayedexpansion
for /f "delims=" %%a in (X:\disk.txt) do (
set "line=%%a"
rem 寻找 * 开头的行
call :is_x_starts_with_char_y "!line!" "*" && (
rem 注意在 for %%b in (!safe_line!) do 中 * 会展开成文件列表,因此要先删除 *
rem 下面用的方法是用 * 作为分割符,获取 * 后面的第一列
rem for /f 会自动忽略行首的分隔符
for /f "tokens=1 delims=*" %%i in ("!line!") do (
set "safe_line=%%i"
)
rem 遍历每一列,找到是数字的那一列,就是磁盘编号
for %%b in (!safe_line!) do (
call :is_number "%%b" && (
set "DiskIndex=%%b"
goto :found_main_disk
)
)
rem 普通 for 是把“一段话”里的“每个词”排成队,让一个变量(%%b轮流去当这些词
rem for /f 是把“一段话”拆成“几个零件”存在不同的变量里(%%i, %%j...
)
) )
:not_found_main_disk
echo Error: Cannot find main disk. >&2
exit /b 1
:found_main_disk
del X:\disk.txt del X:\disk.txt
endlocal & set "DiskIndex=%DiskIndex%"
rem 判断 efi 还是 bios
rem 或者用 https://learn.microsoft.com/windows-hardware/manufacture/desktop/boot-to-uefi-mode-or-legacy-bios-mode
rem pe 下没有 mountvol
echo list vol | diskpart | find " efi " && (
set BootType=efi
) || (
set BootType=bios
)
rem 这个变量会被 trans.sh 修改 rem 这个变量会被 trans.sh 修改
set is4kn=0 set is4kn=0
@ -105,6 +150,7 @@ rem 重新分区/格式化
(if "%BootType%"=="efi" ( (if "%BootType%"=="efi" (
echo select disk %DiskIndex% echo select disk %DiskIndex%
rem del
echo select part 1 echo select part 1
echo delete part override echo delete part override
echo select part 2 echo select part 2
@ -112,26 +158,35 @@ rem 重新分区/格式化
echo select part 3 echo select part 3
echo delete part override echo delete part override
rem 1
echo create part efi size=%EFISize% echo create part efi size=%EFISize%
echo format fs=fat32 quick echo format fs=fat32 quick
rem 2
echo create part msr size=16 echo create part msr size=16
rem 3
echo create part primary echo create part primary
echo format fs=ntfs quick echo format fs=ntfs quick
rem echo assign letter=Z rem echo assign letter=Z
) else ( ) else (
echo select disk %DiskIndex% echo select disk %DiskIndex%
rem del
echo select part 1 echo select part 1
rem echo delete part override echo delete part override
rem echo create part primary
rem 1
echo create part primary
echo format fs=ntfs quick echo format fs=ntfs quick
echo active echo active
rem echo assign letter=Z rem echo assign letter=Z
)) > X:\diskpart.txt )) > X:\diskpart.txt
rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令 rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令
rem 但是返回值始终是 0
diskpart /s X:\diskpart.txt diskpart /s X:\diskpart.txt
del X:\diskpart.txt del X:\diskpart.txt
@ -140,6 +195,11 @@ rem X boot.wim (ram)
rem Y installer rem Y installer
rem Z os rem Z os
rem 获取 BuildNumber
for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do (
set "BuildNumber=%%a"
)
rem 旧版安装程序会自动在C盘设置虚拟内存新版安装程序(24h2)不会 rem 旧版安装程序会自动在C盘设置虚拟内存新版安装程序(24h2)不会
rem 如果不创建虚拟内存1g 内存的机器安装时会报错/杀进程 rem 如果不创建虚拟内存1g 内存的机器安装时会报错/杀进程
if %BuildNumber% GEQ 26040 ( if %BuildNumber% GEQ 26040 (
@ -180,11 +240,25 @@ rem 运行 ramdisk X:\setup.exe 的话
rem vista 会找不到安装源 rem vista 会找不到安装源
rem server 23h2 会无法运行 rem server 23h2 会无法运行
rem 使用 /installfrom 可以解决? rem 使用 /installfrom 可以解决?
if "%ForceOldSetup%"=="1" (
rem 有的精简版 iso install.wim 根目录没有 setup.exe
rem https://github.com/bin456789/reinstall/issues/578
if "%ForceOldSetup%"=="1" if exist Y:\sources\setup.exe (
set setup=Y:\sources\setup.exe set setup=Y:\sources\setup.exe
) else ( goto :SetupExeFound
set setup=Y:\setup.exe
) )
if exist Y:\setup.exe (
set setup=Y:\setup.exe
) else if exist Y:\sources\setup.exe (
set setup=Y:\sources\setup.exe
) else if exist X:\setup.exe (
set setup=X:\setup.exe
) else (
echo "Error: setup.exe not found." >&2
exit /b 1
)
:SetupExeFound
if "%EnableUnattended%"=="1" ( if "%EnableUnattended%"=="1" (
set Unattended=/unattend:X:\windows.xml set Unattended=/unattend:X:\windows.xml
@ -222,6 +296,27 @@ echo on
%setup% %ResizeRecoveryPartition% %EMS% %Unattended% %setup% %ResizeRecoveryPartition% %EMS% %Unattended%
exit /b exit /b
:is_number
rem 尝试转换字符串为数字,如果转换失败则说明不是数字
rem 如果转换失败num 是 0
rem 这不影响参数是 0 时的判断
set /a "num=%~1" >nul 2>nul
if "%num%"=="%~1" (
exit /b 0
)
exit /b 1
:is_x_starts_with_char_y
set "tempStr=%~1"
if "%tempStr:~0,1%"=="%~2" (
exit /b 0
)
exit /b 1
:sleep :sleep
rem 没有加载网卡驱动,无法用 ping 来等待 rem 没有加载网卡驱动,无法用 ping 来等待
rem 没有 timeout 命令 rem 没有 timeout 命令
@ -246,6 +341,12 @@ exit /b
rem 不要查找 Class=SCSIAdapter 因为有些驱动等号两边有空格 rem 不要查找 Class=SCSIAdapter 因为有些驱动等号两边有空格
find /i "SCSIAdapter" "%~1" >nul find /i "SCSIAdapter" "%~1" >nul
if not errorlevel 1 ( if not errorlevel 1 (
rem 有 N 种方法安装驱动
rem 1. dism /online /add-driver /driver:"%~1" # PE 不支持 /online 添加驱动
rem 2. pnputil -i -a "%~1"
rem 3. devcon
rem 4. dpinst
rem 5. drvload 官方推荐 https://learn.microsoft.com/windows-hardware/manufacture/desktop/drvload-command-line-options
drvload "%~1" drvload "%~1"
) )
exit /b exit /b

View File

@ -86,7 +86,7 @@
<Order>4</Order> <Order>4</Order>
<Path>powercfg /setactive SCHEME_MIN</Path> <Path>powercfg /setactive SCHEME_MIN</Path>
</RunSynchronousCommand> </RunSynchronousCommand>
<!-- 启用 administrator 账户 --> <!-- 按需启用 administrator 账户 -->
<RunSynchronousCommand wcm:action="add"> <RunSynchronousCommand wcm:action="add">
<Order>5</Order> <Order>5</Order>
<!-- vista 没有自带 powershell --> <!-- vista 没有自带 powershell -->
@ -94,7 +94,8 @@
<!-- win7 此时无法用 wmic useraccount --> <!-- win7 此时无法用 wmic useraccount -->
<!-- <Path>wmic useraccount where "sid like '%-500'" set Disabled=false</Path> --> <!-- <Path>wmic useraccount where "sid like '%-500'" set Disabled=false</Path> -->
<!-- https://learn.microsoft.com/archive/technet-wiki/13813.localized-names-for-administrator-account-in-windows --> <!-- https://learn.microsoft.com/archive/technet-wiki/13813.localized-names-for-administrator-account-in-windows -->
<Path>cmd /c "for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes &amp;&amp; exit)"</Path> <!-- %enable_administrator% 会被 trans.sh 替换成 1 或 0 -->
<Path>cmd /c "if "%enable_administrator%"=="1" for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes &amp;&amp; exit)"</Path>
</RunSynchronousCommand> </RunSynchronousCommand>
<!-- 禁用保留空间 --> <!-- 禁用保留空间 -->
<RunSynchronousCommand wcm:action="add"> <RunSynchronousCommand wcm:action="add">
@ -152,10 +153,24 @@
<Value>%administrator_password%</Value> <Value>%administrator_password%</Value>
<PlainText>false</PlainText> <PlainText>false</PlainText>
</AdministratorPassword> </AdministratorPassword>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Name>%user_username%</Name>
<Password>
<Value>%user_password%</Value>
<PlainText>false</PlainText>
</Password>
<!-- 需要填英文的 Administrators任何语言都是 -->
<!-- https://learn.microsoft.com/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-useraccounts-localaccounts-localaccount-group -->
<Group>Administrators</Group>
</LocalAccount>
</LocalAccounts>
</UserAccounts> </UserAccounts>
<OOBE> <OOBE>
<HideEULAPage>true</HideEULAPage> <HideEULAPage>true</HideEULAPage>
<ProtectYourPC>3</ProtectYourPC> <!-- 文档说请勿使用 SkipMachineOOBE 设置自动执行 OOBE -->
<!-- 但是 Azure 的系统镜像也是用了 SkipMachineOOBE -->
<!-- https://learn.microsoft.com/windows-hardware/customize/desktop/automate-oobe -->
<SkipMachineOOBE>true</SkipMachineOOBE> <SkipMachineOOBE>true</SkipMachineOOBE>
<SkipUserOOBE>true</SkipUserOOBE> <SkipUserOOBE>true</SkipUserOOBE>
</OOBE> </OOBE>

View File

@ -1,36 +1,59 @@
param( param(
[string]$Namespace, [string]$Namespace = "root\cimv2",
[string]$Class, [Parameter(Mandatory = $true)] [string]$Class,
[string]$Filter, [string]$Filter,
[string]$Properties [string]$Properties
) )
$propertiesToDisplay = if ($Properties) { $Properties.Split(",") } else { @("*") } # 预处理属性列表:如果有输入则处理成数组,否则保持为空数组
[string[]]$propertyList = if ($Properties) {
$wmiQuery = @{ $Properties.Split(",") | ForEach-Object { $_.Trim() }
Namespace = $Namespace }
Class = $Class else {
@()
} }
if ($Filter) { # 检查是否支持 Get-Cimresult
$wmiQuery.Filter = $Filter $isSupportCim = [bool](Get-Command Get-Cimresult -ErrorAction SilentlyContinue)
# 构造查询参数
$queryParams = @{ Namespace = $Namespace }
if ($isSupportCim) { $queryParams.ClassName = $Class } else { $queryParams.Class = $Class }
if ($Filter) { $queryParams.Filter = $Filter }
# 限制查询属性,加快查询速度
# CIM 支持
# WIM 不支持
if ($isSupportCim -and $propertyList.Count -gt 0) {
$queryParams.Property = $propertyList
} }
Get-WmiObject @wmiQuery | ForEach-Object { # 执行查询
$_.PSObject.Properties | Where-Object { $results = if ($isSupportCim) { Get-Cimresult @queryParams } else { Get-WmiObject @queryParams }
-not $_.Name.StartsWith("__") -and
($propertiesToDisplay -contains $_.Name -or $propertiesToDisplay -contains "*")
} | ForEach-Object {
$name = $_.Name
$value = $_.Value
# 改成 wmic 的输出格式 # 遍历结果
if ($value -is [Array]) { foreach ($result in $results) {
$formattedValue = ($value | ForEach-Object { "`"$_`"" }) -join "," # 遍历属性
Write-Output "$name={$formattedValue}" foreach ($property in $result.PSObject.Properties) {
} $name = $property.Name
else { $value = $property.Value
Write-Output "$name=$value"
# 过滤系统属性
if ($name.StartsWith("__") -or $name -eq "CimresultProperties" -or $name -eq "CimClass") { continue }
# 只输出 propertyList 有的属性
# propertyList 为空表示不过滤
if ($propertyList.Count -eq 0 -or $propertyList -contains $name) {
# 改成 wmic 的输出格式
# 这里要注意 string 也是 IEnumerable
if ($value -isnot [string] -and $value -is [Collections.IEnumerable]) {
$formattedValue = ($value | ForEach-Object { "`"$_`"" }) -join ","
Write-Output "$name={$formattedValue}"
}
else {
Write-Output "$name=$value"
}
} }
} }
} }