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 }} 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

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://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://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 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://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (Rolling) | 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 | 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://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 |
@ -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.
- 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.
- 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/`.
@ -163,11 +163,11 @@ bash reinstall.sh anolis 7|8|23
centos 9|10
fnos 1
nixos 25.11
fedora 42|43
fedora 43|44
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
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]
kali
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.
- Username `administrator`. The script prompts for a password. If left blank, a random one is generated.
- If remote login fails, try using the username `.\administrator`.
- The script prompts for a username. If left blank, will use `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.
- Supports ISO images in any language.
- Supports bypassing Windows 11 hardware requirements.
- Automatically bypassing Windows 11 hardware requirements.
#### Supported Systems
@ -446,6 +447,7 @@ bash reinstall.sh windows \
#### Optional Parameters
- `--username USERNAME` Set Username (for Windows only)
- `--password PASSWORD` Set Password
- `--allow-ping` Configure Windows Firewall to Allow Ping Responses
- `--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.
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.
Replace `xxxxxxxx` in the script below with the `commit_id` of an older version and run the script.
```bash
commit_id=xxxxxxx
commit_id=xxxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ...
@ -598,6 +602,7 @@ bash reinstall.sh ...
1. Fork this repository.
2. Modify the `confhome` and `confhome_cn` at the beginning of `reinstall.sh` and `reinstall.bat`.
3. Make changes to the other code.
4. Download and run your `reinstall.sh` or `reinstall.bat`."
## 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://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://fedoraproject.org/favicon.ico" /> Fedora | 42, 43 | 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://static.opensuse.org/favicon.ico" /> openSUSE | Leap 15.6, 16.0, Tumbleweed (滚动) | 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 | 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://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 |
@ -149,7 +149,7 @@ certutil -urlcache -f -split https://cnb.cool/bin456789/reinstall/-/git/raw/main
- 用户名为 `root`,脚本会提示输入密码,不输入则使用随机密码
- 安装最新版可不输入版本号
- 最大化利用磁盘空间:不含 boot 分区Fedora 例外),不含 swap 分区
- 最大化利用磁盘空间:不含 boot swap 分区
- 自动根据机器类型选择不同的优化内核,例如 `Cloud``HWE` 内核
- 安装 Red Hat 时需填写 <https://access.redhat.com/downloads/content/rhel> 得到的 `qcow2` 镜像链接,也可以安装其它类 RHEL 系统的 `qcow2`,例如 `Alibaba Cloud Linux``TencentOS Server`
- 重装后如需修改 SSH 端口或者改成密钥登录,注意还要修改 `/etc/ssh/sshd_config.d/` 里面的文件
@ -163,11 +163,11 @@ bash reinstall.sh anolis 7|8|23
centos 9|10
fnos 1
nixos 25.11
fedora 42|43
fedora 43|44
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
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]
kali
arch
@ -327,11 +327,12 @@ bash reinstall.sh netboot.xyz
>
> 如果不小心运行了脚本,可以在重启前运行 `bash reinstall.sh reset` 取消重装
-户名为 `administrator`,脚本会提示输入密码,不输入则使用随机密码
- 如果远程登录失败,可以尝试使用用户名 `.\administrator`
- 脚本会提示输入用户名,不输入则使`administrator`
- 脚本会提示输入密码,不输入则使用随机密码
- 如果远程登录失败,请尝试在用户名前添加 `.\`,例如 `.\administrator`
- 静态机器会自动配置好 IP可能首次开机几分钟后才生效
- 支持任意语言的 ISO
- 支持绕过 Windows 11 硬件限制
- 自动绕过 Windows 11 硬件限制
#### 支持的系统
@ -446,6 +447,7 @@ bash reinstall.sh windows \
#### 可选参数
- `--username USERNAME` 设置用户名(仅限 Windows
- `--password PASSWORD` 设置密码
- `--allow-ping` 设置 Windows 防火墙允许被 Ping
- `--rdp-port PORT` 更改 RDP 端口
@ -582,12 +584,14 @@ bash reinstall.sh reset
根据 Bug 守恒定律,修复旧 Bug 的同时会引入新的 Bug
如果遇到新的 Bug,可以试下旧版本是否正常
如果脚本出现问题,可以试下旧版本是否正常
<https://github.com/bin456789/reinstall/commits/main> 右侧找到旧版本的 `commit_id`
将下面脚本的 `xxxxxxxx` 替换成旧版本的 `commit_id` 并运行脚本
```bash
commit_id=xxxxxxx
commit_id=xxxxxxxx
curl -O https://raw.githubusercontent.com/bin456789/reinstall/$commit_id/reinstall.sh || wget -O ${_##*/} $_
sed -i "/^confhome.*main$/s/main/$commit_id/" reinstall.sh
bash reinstall.sh ...
@ -598,6 +602,7 @@ bash reinstall.sh ...
1. Fork 本仓库
2. 修改 `reinstall.sh``reinstall.bat` 开头的 `confhome``confhome_cn`
3. 修改其它代码
4. 下载并运行你的 `reinstall.sh``reinstall.bat`
## 感谢

View File

@ -170,47 +170,6 @@ GatewayOnLink=yes
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,因此不用处理
# debian 10/11 云镜像原本用 ifupdown + resolvconf脚本改成用 netplan + networkd/resolved
@ -224,6 +183,3 @@ fix_netplan_conf
# 只需对云镜像处理
# 因为普通安装用的是 alpine 的 cloud-init版本够新不用处理
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=systemd-networkd.service
Before=NetworkManager.service
Before=wickedd-auto4.service
Before=wickedd-dhcp4.service
Before=wickedd-dhcp6.service
Before=wickedd.service
Before=network.target

View File

@ -84,11 +84,11 @@ Usage: $reinstall_____ anolis 7|8|23
centos 9|10
fnos 1
nixos 25.11
fedora 42|43
fedora 43|44
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
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]
kali
arch
@ -643,13 +643,12 @@ wmic() {
curl -Lo "$tmp/wmic.ps1" "$confhome/wmic.ps1"
fi
# shellcheck disable=SC2046
powershell -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass \
-File "$(cygpath -w "$tmp/wmic.ps1")" \
-Namespace "$namespace" \
-Class "$class" \
$([ -n "$filter" ] && echo -Filter "$filter") \
$([ -n "$props" ] && echo -Properties "$props")
${filter:+"-Filter"} ${filter:+"$filter"} \
${props:+"-Properties"} ${props:+"$props"}
}
is_virt() {
@ -703,12 +702,6 @@ is_virt() {
$_is_virt
}
is_absolute_path() {
# 检查路径是否以/开头
# 注意语法和 ash 不同
[[ "$1" = /* ]]
}
is_cpu_supports_x86_64_v3() {
# 用 ld.so/cpuid/coreinfo.exe 更准确
# centos 7 /usr/lib64/ld-linux-x86-64.so.2 没有 --help
@ -1486,13 +1479,11 @@ Continue?
# leap
dir=distribution/leap/$releasever/appliances
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-kvm$(if [ "$basearch" = x86_64 ]; then echo '-and-xen'; fi).qcow2 ;;
esac
# 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
# 有专门的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
@ -1917,12 +1908,12 @@ verify_os_name() {
'rocky 8|9|10' \
'oracle 8|9|10' \
'fnos 1' \
'fedora 42|43' \
'fedora 43|44' \
'nixos 25.11' \
'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' \
'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' \
'redhat' \
'kali' \
@ -2349,6 +2340,59 @@ trim() {
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() {
info "prompt 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/')
fi
if ! {
res=$(efibootmgr --create-only \
--disk "/dev/$(get_disk_by_part $dev_part)" \
--part "$(get_part_num_by_part $dev_part)" \
--label "$(get_entry_name)" \
--loader "\\EFI\\reinstall\\$basename") &&
id=$(echo "$res" | grep_efi_entry | tail -1 | grep_efi_index | grep .) &&
efibootmgr --bootnext "$id"
}; then
set -- efibootmgr --create-only \
--disk "/dev/$(get_disk_by_part $dev_part)" \
--part "$(get_part_num_by_part $dev_part)" \
--label "$(get_entry_name)" \
--loader "\\EFI\\reinstall\\$basename"
if ! res=$("$@"); then
echo "Command: $*"
echo "$res"
error_and_exit "Could not add efi entry."
fi
id=$(echo "$res" | grep_efi_entry | tail -1 | grep_efi_index | grep .)
efibootmgr --bootnext "$id"
}
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
for key in confhome hold force_boot_mode force_cn force_old_windows_setup cloud_image main_disk \
elts deb_mirror \
ssh_port rdp_port web_port allow_ping; do
username ssh_port rdp_port web_port allow_ping; do
value=${!key}
if [ -n "$value" ]; then
is_need_quote "$value" &&
@ -3230,7 +3276,7 @@ build_cmdline() {
# 脚本可能多次运行,先清理之前的残留
mkdir_clear() {
dir=$1
local dir=$1
if [ -z "$dir" ] || [ "$dir" = / ]; then
return
@ -3411,6 +3457,32 @@ EOF
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
# 在 debian installer 中判断能否用云内核
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/
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
if [ $ram_size -gt 256 ] || is_in_windows; then
sed -i '/^pata-modules/d' $net_retriever
@ -3505,27 +3595,11 @@ EOF
# xen 还需要以下两个?
# kernel/drivers/xen/xen-scsiback.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
mkdir_clear $tmp/scsi
download_and_extract_deb udeb scsi-modules-$kver-di $tmp/scsi
relative_drivers_dir=lib/modules/$kver/kernel/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
)
cp_debian_kali_driver $tmp/scsi "$extra_drivers"
fi
fi
@ -3580,6 +3654,7 @@ get_net_drivers() {
# 不用在 windows 判断是哪种硬盘/网络驱动,因为 256M 运行 windows 只可能是 xp而脚本本来就不支持 xp
# 而且安装过程也有二次判断
# trans.sh 有同名方法
get_drivers() {
# 有以下结果组合出现
# sd_mod
@ -3590,6 +3665,7 @@ get_drivers() {
# xen_blkfront
# ahci
# nvme
# pci_hyperv
# mptspi
# mptsas
# vmw_pvscsi
@ -3863,6 +3939,7 @@ This script is outdated, please download reinstall.sh again.
if [ "$hold" = 0 ]; then
info 'hold 0'
echo "Edit $tmp if needed."
read -r -p 'Press Enter to continue...'
fi
@ -4117,7 +4194,7 @@ recreate_grub_or_extlinux_cfg() {
/nix/var/nix/profiles/system/bin/switch-to-configuration boot
# 手动启用 41_custom
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
update-grub
else
@ -4286,6 +4363,7 @@ for o in ci installer debug minimal allow-ping force-cn help \
img: \
cloud-data: \
lang: \
user: username: \
passwd: password: \
ssh-port: \
ssh-key: public-key: \
@ -4420,6 +4498,14 @@ while true; do
force_boot_mode=$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)
[ -n "$2" ] || error_and_exit "Need value for $1"
password=$2
@ -4595,6 +4681,11 @@ done
# 检查必须的参数
verify_os_args
# 用户名
if [ "$distro" = windows ] && [ -z "$username" ]; then
prompt_username
fi
# 密码
if ! is_netboot_xyz && [ -z "$ssh_keys" ] && [ -z "$password" ]; then
if is_use_dd; then
@ -4874,7 +4965,7 @@ info 'info'
echo "$distro $releasever"
case "$distro" in
windows) username=administrator ;;
windows) username=${username:-administrator} ;;
netboot.xyz) username= ;;
dd | *) username=root ;;
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
# 最后一个 tty 是主 tty显示的信息最全
is_first=true
if [ "$(uname -m)" = "aarch64" ]; then
ttys="ttyS0 ttyAMA0 tty0"
else
ttys="ttyS0 tty0"
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
# hytron 有ttyS0 但无法写入
if stty -g -F "/dev/$tty" >/dev/null 2>&1; then
if $is_for_cmdline || stty -g -F "/dev/$tty" >/dev/null 2>&1; then
if $is_first; then
is_first=false
else
@ -25,7 +33,7 @@ for tty in $ttys; do
printf "%s" "$prefix$tty"
if [ "$prefix" = "console=" ] &&
if $is_for_cmdline &&
{ [ "$tty" = ttyS0 ] || [ "$tty" = ttyAMA0 ]; }; then
printf ",115200n8"
fi

View File

@ -1,6 +1,6 @@
#!/bin/ash
# shellcheck shell=dash
# shellcheck disable=SC3001,SC3003,SC3010
# shellcheck disable=SC3001,SC3003,SC3010,SC3015
# reinstall.sh / trans.sh 共用此文件
# grep 无法处理 UTF-16LE 编码的 inf有以下几种解决方法
@ -239,6 +239,27 @@ list_files_from_inf() {
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 里有列出其它架构的驱动
# 因此 DISM 导出驱动时,也就没有包含其它架构的驱动文件
@ -284,7 +305,11 @@ get_path_in_correct_case() {
output="$output$part/"
else
# 最后 part
output="$output$part"
if is_x_ends_with_y "$path" /; then
output="$output$part/"
else
output="$output$part"
fi
fi
shift
done

View File

@ -49,29 +49,22 @@ if exist X:\custom_drivers\ (
rem 等待加载分区
call :sleep 5000
echo rescan | diskpart
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
)
call :sleep 5000
rem 获取 ProductType
rem for /f "tokens=3" %%a in ('reg query "HKLM\SYSTEM\CurrentControlSet\Control\ProductOptions" /v ProductType') do (
rem set "ProductType=%%a"
rem )
rem 获取 BuildNumber
for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do (
set "BuildNumber=%%a"
rem 获取 installer 卷 id
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find " installer "') do (
set "VolIndex=%%a"
)
rem 获取 installer 卷 id
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do (
set "VolIndex=%%a"
rem 及时退出
if "%VolIndex%"=="" (
echo Error: Cannot find installer partition. >&2
exit /b 1
)
rem 将 installer 分区设为 Y 盘
@ -87,11 +80,63 @@ rem wmic pagefile
rem 获取主硬盘 id
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 (
set "DiskIndex=%%a"
rem 法语版 win7 diskpart 始终输出法语,即使设置了 chcp 437因此不能用这个方法
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
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 修改
set is4kn=0
@ -105,6 +150,7 @@ rem 重新分区/格式化
(if "%BootType%"=="efi" (
echo select disk %DiskIndex%
rem del
echo select part 1
echo delete part override
echo select part 2
@ -112,26 +158,35 @@ rem 重新分区/格式化
echo select part 3
echo delete part override
rem 1
echo create part efi size=%EFISize%
echo format fs=fat32 quick
rem 2
echo create part msr size=16
rem 3
echo create part primary
echo format fs=ntfs quick
rem echo assign letter=Z
) else (
echo select disk %DiskIndex%
rem del
echo select part 1
rem echo delete part override
rem echo create part primary
echo delete part override
rem 1
echo create part primary
echo format fs=ntfs quick
echo active
rem echo assign letter=Z
)) > X:\diskpart.txt
rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令
rem 使用 diskpart /s ,出错不会执行剩下的 diskpart 命令
rem 但是返回值始终是 0
diskpart /s X:\diskpart.txt
del X:\diskpart.txt
@ -140,6 +195,11 @@ rem X boot.wim (ram)
rem Y installer
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 如果不创建虚拟内存1g 内存的机器安装时会报错/杀进程
if %BuildNumber% GEQ 26040 (
@ -180,11 +240,25 @@ rem 运行 ramdisk X:\setup.exe 的话
rem vista 会找不到安装源
rem server 23h2 会无法运行
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
) else (
set setup=Y:\setup.exe
goto :SetupExeFound
)
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" (
set Unattended=/unattend:X:\windows.xml
@ -222,6 +296,27 @@ echo on
%setup% %ResizeRecoveryPartition% %EMS% %Unattended%
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
rem 没有加载网卡驱动,无法用 ping 来等待
rem 没有 timeout 命令
@ -246,6 +341,12 @@ exit /b
rem 不要查找 Class=SCSIAdapter 因为有些驱动等号两边有空格
find /i "SCSIAdapter" "%~1" >nul
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"
)
exit /b

View File

@ -86,7 +86,7 @@
<Order>4</Order>
<Path>powercfg /setactive SCHEME_MIN</Path>
</RunSynchronousCommand>
<!-- 启用 administrator 账户 -->
<!-- 按需启用 administrator 账户 -->
<RunSynchronousCommand wcm:action="add">
<Order>5</Order>
<!-- vista 没有自带 powershell -->
@ -94,7 +94,8 @@
<!-- win7 此时无法用 wmic useraccount -->
<!-- <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 -->
<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 wcm:action="add">
@ -152,10 +153,24 @@
<Value>%administrator_password%</Value>
<PlainText>false</PlainText>
</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>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<ProtectYourPC>3</ProtectYourPC>
<!-- 文档说请勿使用 SkipMachineOOBE 设置自动执行 OOBE -->
<!-- 但是 Azure 的系统镜像也是用了 SkipMachineOOBE -->
<!-- https://learn.microsoft.com/windows-hardware/customize/desktop/automate-oobe -->
<SkipMachineOOBE>true</SkipMachineOOBE>
<SkipUserOOBE>true</SkipUserOOBE>
</OOBE>

View File

@ -1,36 +1,59 @@
param(
[string]$Namespace,
[string]$Class,
[string]$Namespace = "root\cimv2",
[Parameter(Mandatory = $true)] [string]$Class,
[string]$Filter,
[string]$Properties
)
$propertiesToDisplay = if ($Properties) { $Properties.Split(",") } else { @("*") }
$wmiQuery = @{
Namespace = $Namespace
Class = $Class
# 预处理属性列表:如果有输入则处理成数组,否则保持为空数组
[string[]]$propertyList = if ($Properties) {
$Properties.Split(",") | ForEach-Object { $_.Trim() }
}
else {
@()
}
if ($Filter) {
$wmiQuery.Filter = $Filter
# 检查是否支持 Get-Cimresult
$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 {
-not $_.Name.StartsWith("__") -and
($propertiesToDisplay -contains $_.Name -or $propertiesToDisplay -contains "*")
} | ForEach-Object {
$name = $_.Name
$value = $_.Value
# 执行查询
$results = if ($isSupportCim) { Get-Cimresult @queryParams } else { Get-WmiObject @queryParams }
# 改成 wmic 的输出格式
if ($value -is [Array]) {
$formattedValue = ($value | ForEach-Object { "`"$_`"" }) -join ","
Write-Output "$name={$formattedValue}"
}
else {
Write-Output "$name=$value"
# 遍历结果
foreach ($result in $results) {
# 遍历属性
foreach ($property in $result.PSObject.Properties) {
$name = $property.Name
$value = $property.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"
}
}
}
}