Compare commits

...

6 Commits

Author SHA1 Message Date
1a1f8ea124 core: 不重要的优化 2026-04-25 23:30:22 +08:00
e7deea5b0f windows: 删除 ProtectYourPC 设置,使首次登录可自定义隐私选项 2026-04-25 23:16:54 +08:00
7402d204fb windows: 优化安装流程 2026-04-25 23:16:54 +08:00
e2a8be7bb7 core: 优化 powershell 查询
- 避免 wmic where 条件有空格时报错
- 减少 ForEach-Object 以提高速度
2026-04-25 23:16:53 +08:00
6341c21d0b windows: 国内服务器访问 intel.cn 2026-04-25 23:16:53 +08:00
5cbc106423 core: 添加 pci-hyperv / vpci.sys 驱动
修复 Azure 安装 debian / windows 10 ltsc 时不到 nvme 硬盘
2026-04-25 23:16:52 +08:00
8 changed files with 362 additions and 101 deletions

View File

@ -331,7 +331,7 @@ bash reinstall.sh netboot.xyz
- If remote login fails, try using the username `.\administrator`. - If remote login fails, try using the username `.\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
@ -582,12 +582,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 +600,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

@ -331,7 +331,7 @@ bash reinstall.sh netboot.xyz
- 如果远程登录失败,可以尝试使用用户名 `.\administrator` - 如果远程登录失败,可以尝试使用用户名 `.\administrator`
- 静态机器会自动配置好 IP可能首次开机几分钟后才生效 - 静态机器会自动配置好 IP可能首次开机几分钟后才生效
- 支持任意语言的 ISO - 支持任意语言的 ISO
- 支持绕过 Windows 11 硬件限制 - 自动绕过 Windows 11 硬件限制
#### 支持的系统 #### 支持的系统
@ -582,12 +582,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 +600,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

@ -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
@ -3230,7 +3223,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 +3404,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 +3490,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 +3542,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 +3601,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 +3612,7 @@ get_drivers() {
# xen_blkfront # xen_blkfront
# ahci # ahci
# nvme # nvme
# pci_hyperv
# mptspi # mptspi
# mptsas # mptsas
# vmw_pvscsi # vmw_pvscsi
@ -3863,6 +3886,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

189
trans.sh
View File

@ -465,7 +465,7 @@ EOF
} }
umount_all() { umount_all() {
dirs="/mnt /os /iso /wim /installer /nbd /nbd-boot /nbd-efi /nbd-test /root /nix" dirs="/mnt /os /iso /wim /wim-tmp /installer /nbd /nbd-boot /nbd-efi /nbd-test /root /nix"
regex=$(echo "$dirs" | sed 's, ,|,g') regex=$(echo "$dirs" | sed 's, ,|,g')
if mounts=$(mount | grep -Ew "on $regex" | awk '{print $3}' | tac); then if mounts=$(mount | grep -Ew "on $regex" | awk '{print $3}' | tac); then
for mount in $mounts; do for mount in $mounts; do
@ -5738,10 +5738,15 @@ get_filesize_mb() {
du -m "$1" | awk '{print $1}' du -m "$1" | awk '{print $1}'
} }
is_absolute_path() { mkdir_clear() {
# 检查路径是否以/开头 local dir=$1
# 注意语法和 bash 不同
[[ "$1" = "/*" ]] if [ -z "$dir" ] || [ "$dir" = / ]; then
return
fi
rm -rf "$dir"
mkdir -p "$dir"
} }
# 注意使用方法是 list=$(list_add "$list" "$item_to_add") # 注意使用方法是 list=$(list_add "$list" "$item_to_add")
@ -5760,6 +5765,23 @@ is_list_has() {
echo "$list" | grep -qFx "$item" echo "$list" | grep -qFx "$item"
} }
# reinstall.sh 有同名方法
get_drivers() {
(
cd "$(readlink -f $1)"
while ! [ "$(pwd)" = / ]; do
if [ -d driver ]; then
if [ -d driver/module ]; then
basename "$(readlink -f driver/module)"
else
basename "$(readlink -f driver)"
fi
fi
cd ..
done
)
}
get_windows_type_from_windows_drive() { get_windows_type_from_windows_drive() {
local os_dir=$1 local os_dir=$1
@ -5795,6 +5817,22 @@ get_windows_arch_from_windows_drive() {
apk del hivex apk del hivex
} }
get_intel_download_url() {
local id=$1
local file_regex=$2
if is_in_china; then
local url=https://www.intel.cn/content/www/cn/zh/download/$id.html
else
local url=https://www.intel.com/content/www/us/en/download/$id.html
fi
# 在每个双引号前和后添加换行符,使每个链接占一行
# intel 禁止了 wget 下载网页
wget -U curl/7.54.1 "$url" -O- | sed 's,",\n"\n,g' |
grep -Eio -m1 "https://.+/$file_regex" | grep .
}
install_windows() { install_windows() {
get_wim_prop() { get_wim_prop() {
wim=$1 wim=$1
@ -5950,14 +5988,21 @@ install_windows() {
installation_type=$(get_selected_image_prop "Installation Type") installation_type=$(get_selected_image_prop "Installation Type")
fi fi
mount_iso_install_wim_to() {
local dir=$1
mkdir -p "$dir"
# shellcheck disable=SC2046
wimmount "$iso_install_wim" "$image_index" "$dir" \
$($is_swm && echo "--ref=$(dirname "$iso_install_wim")/$swm_ref")
}
# 挂载 install.wim检查 # 挂载 install.wim检查
# 1. 是否自带 sac 组件 # 1. 是否自带 sac 组件
# 2. 是否自带 nvme 驱动 # 2. 是否自带 nvme 驱动
# 3. 是否支持 sha256 # 3. 是否支持 sha256
# 4. Installation Type # 4. Installation Type
# shellcheck disable=SC2046 mount_iso_install_wim_to /wim
wimmount "$iso_install_wim" "$image_index" /wim/ \
$($is_swm && echo --ref=$(dirname "$iso_install_wim")/$swm_ref)
# 获取版本号 # 获取版本号
get_windows_version_from_windows_drive /wim get_windows_version_from_windows_drive /wim
@ -5974,7 +6019,7 @@ install_windows() {
# 检测 sac 和 nvme # 检测 sac 和 nvme
{ {
find_file_ignore_case /wim/Windows/System32/sacsess.exe && has_sac=true || has_sac=false find_file_ignore_case /wim/Windows/System32/sacsess.exe && has_sac=true || has_sac=false
find_file_ignore_case /wim/Windows/INF/stornvme.inf && has_stornvme=true || has_stornvme=false find_file_ignore_case /wim/Windows/System32/drivers/stornvme.sys && has_stornvme=true || has_stornvme=false
} >/dev/null 2>&1 } >/dev/null 2>&1
# 检测是否支持 sha256 签名的驱动 # 检测是否支持 sha256 签名的驱动
@ -6194,8 +6239,9 @@ install_windows() {
add_drivers() { add_drivers() {
info "Add drivers" info "Add drivers"
# 驱动下载临时文件夹
drv=/os/drivers drv=/os/drivers
mkdir -p "$drv" # 驱动下载临时文件夹 mkdir_clear "$drv"
# 这里有坑 # 这里有坑
# $(get_cloud_vendor) 调用了 cache_dmi_and_virt # $(get_cloud_vendor) 调用了 cache_dmi_and_virt
@ -6254,6 +6300,26 @@ install_windows() {
add_driver_vmd add_driver_vmd
fi fi
# 主网卡,有 IP 地址
# root@localhost:~# get_drivers /sys/class/net/eth0
# hv_netvsc
# 加速网卡,无 IP 地址
# root@localhost:~# get_drivers /sys/class/net/enP30832s1
# mana
# pci_hyperv
# vpci
# 对应 linux 的 pci_hyperv
# win10 ltsc 2021 boot.wim 没有 vpci.sys导致找不到 azure nvme 硬盘
# 要从 install.wim 提取
# PE 下不用上网,因此不需要检测网卡是否用 pci_hyperv
if [ -d /sys/module/pci_hyperv ] &&
get_drivers "/sys/block/$xda" | grep -qx pci_hyperv &&
! find_file_ignore_case /wim/Windows/System32/drivers/vpci.sys >/dev/null 2>&1; then
add_driver_vpci
fi
# 厂商驱动 # 厂商驱动
case "$vendor" in case "$vendor" in
aws) aws)
@ -6333,9 +6399,7 @@ install_windows() {
2025) echo 838943 ;; 2025) echo 838943 ;;
esac esac
) )
# intel 禁止了 wget 下载网页 get_intel_download_url "$id" "(Wired_driver|prowin).*${arch_intel}(legacy)?\.(zip|exe)"
wget -U curl/7.54.1 https://www.intel.com/content/www/us/en/download/$id.html -O- |
grep -Eio -m1 "\"https://.+/(Wired_driver|prowin).*${arch_intel}(legacy)?\.(zip|exe)\"" | tr -d '"' | grep .
;; ;;
esac ;; esac ;;
esac esac
@ -6685,8 +6749,7 @@ EOF
cp_drivers $drv/virtio -ipath "*/$virtio_sys/$arch/*" "$@" cp_drivers $drv/virtio -ipath "*/$virtio_sys/$arch/*" "$@"
fi fi
else else
# coreutils 的 cp mv rm 才有 -v 参数 apk add 7zip file
apk add 7zip file coreutils
download $baseurl/$dir/virtio-win-gt-$arch_xdd.msi $drv/virtio.msi download $baseurl/$dir/virtio-win-gt-$arch_xdd.msi $drv/virtio.msi
match="FILE_*_${virtio_sys}_${arch}*" match="FILE_*_${virtio_sys}_${arch}*"
7z x $drv/virtio.msi -o$drv/virtio -i!$match -y -bb1 7z x $drv/virtio.msi -o$drv/virtio -i!$match -y -bb1
@ -6936,7 +6999,91 @@ EOF
cp_drivers $drv/azure cp_drivers $drv/azure
} }
# vpci
add_driver_vpci() {
info "Add drivers: vpci"
mount_iso_install_wim_to /wim-tmp
# 检查 install.wim 镜像是否有 vpci 驱动
if vpci_sys=$(find_file_ignore_case /wim-tmp/Windows/System32/drivers/vpci.sys) &&
wvpci_inf=$(find_file_ignore_case /wim-tmp/Windows/INF/wvpci.inf); then
# 注册表文件
from_system_hive="$(find_file_ignore_case /wim-tmp/Windows/System32/config/SYSTEM)"
from_software_hive="$(find_file_ignore_case /wim-tmp/Windows/System32/config/SOFTWARE)"
to_system_hive="$(find_file_ignore_case /wim/Windows/System32/config/SYSTEM)"
to_software_hive="$(find_file_ignore_case /wim/Windows/System32/config/SOFTWARE)"
# TODO: alpine 3.24 发布后删除
# hivex-perl 要从 edge/community 仓库下载
alpine_mirror=$(grep '^http.*/main$' /etc/apk/repositories | sed 's,/[^/]*/main$,,' | head -1)
apk add --repository "$alpine_mirror/edge/community" \
--force-non-repository \
--virtual edge \
hivex-perl
# 获取当前生效的 wvpci.inf 文件
# 得到 wvpci.inf_amd64_86afbe8940682d27 这样的文件名
wvpci_inf_filename_with_hash=$(hivexget "$from_system_hive" 'DriverDatabase\DriverInfFiles\wvpci.inf' Active)
# .inf .sys
cp -fv "$vpci_sys" "$(get_path_in_correct_case /wim/Windows/System32/drivers/)"
cp -fv "$wvpci_inf" "$(get_path_in_correct_case /wim/Windows/INF/)"
cp -rfv "$(get_path_in_correct_case "/wim-tmp/Windows/System32/DriverStore/FileRepository/$wvpci_inf_filename_with_hash/")" \
"$(get_path_in_correct_case /wim/Windows/System32/DriverStore/FileRepository/)"
# .cat
apk add binutils
for file in "$(get_path_in_correct_case '/wim-tmp/Windows/System32/CatRoot/{F750E6C3-38EE-11D1-85E5-00C04FC295EE}/')"*; do
if strings -e l "$file" | grep -iq vpci.sys; then
cp -fv "$file" "$(get_path_in_correct_case '/wim/Windows/System32/CatRoot/{F750E6C3-38EE-11D1-85E5-00C04FC295EE}/')"
fi
done
apk del binutils
mkdir -p "$drv/vpci"
# SOFTWARE
reg=$drv/vpci/software.reg
# shellcheck disable=SC2043
for key in \
"Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vpci.sys"; do
hivexregedit --export "$from_software_hive" "$key" >>"$reg"
done
hivexregedit --merge "$to_software_hive" "$reg"
# SYSTEM
# 理论上要从 HKEY_LOCAL_MACHINE\SYSTEM\Select 的 Current/Default 获取 ControlSet 序号
reg=$drv/vpci/system.reg
for key in \
"ControlSet001\Services\EventLog\System\vpci" \
"ControlSet001\Services\vpci" \
"DriverDatabase\DeviceIds\VMBUS\{44C4F61D-4444-4400-9D52-802E27EDE19F}" \
"DriverDatabase\DriverInfFiles\wvpci.inf" \
"DriverDatabase\DriverPackages\\$wvpci_inf_filename_with_hash"; do
hivexregedit --export "$from_system_hive" "$key" >>"$reg"
done
# 这个注册表位置用 Tag 记录着驱动加载的顺序
# HKEY_LOCAL_MACHINE\System\ControlSet001\Control\GroupOrderList 的 System Bus Extender
# 因此要删除 vpci 的 tag避免 tag 跟其他驱动重复,而导致错误
cat <<EOF >>"$reg"
[\ControlSet001\Services\vpci]
"Tag"=-
EOF
hivexregedit --merge "$to_system_hive" "$reg"
apk del edge
else
error_and_exit "vpci driver not found."
fi
wimunmount /wim-tmp
}
add_driver_vmd() { add_driver_vmd() {
info "Add drivers: VMD"
# RST v20 不支持 11代 PCI\VEN_8086&DEV_9A0B # RST v20 不支持 11代 PCI\VEN_8086&DEV_9A0B
support_v19=false support_v19=false
support_v20=false support_v20=false
@ -6954,18 +7101,16 @@ EOF
fi fi
done done
local page= local id
if $support_v20 && [ "$build_ver" -ge 19041 ]; then if $support_v20 && [ "$build_ver" -ge 19041 ]; then
page=https://www.intel.com/content/www/us/en/download/849936.html id=849936
elif $support_v19 && [ "$build_ver" -ge 15063 ]; then elif $support_v19 && [ "$build_ver" -ge 15063 ]; then
page=https://www.intel.com/content/www/us/en/download/849933.html id=849933
fi fi
if [ -n "$page" ]; then if [ -n "$id" ]; then
# intel 禁止了 wget 下载网页
local url local url
url=$(wget -U curl/7.54.1 "$page" -O- | url=$(get_intel_download_url "$id" "SetupRST\.exe")
grep -Eio -m1 "\"https://.+/SetupRST\.exe\"" | tr -d '"' | grep .)
# 注意 intel 禁止了 aria2 下载 # 注意 intel 禁止了 aria2 下载
download $url $drv/SetupRST.exe download $url $drv/SetupRST.exe

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,31 +49,24 @@ 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
for /f "tokens=3" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v CurrentBuildNumber') do (
set "BuildNumber=%%a"
)
rem 获取 installer 卷 id rem 获取 installer 卷 id
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do ( for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| find "installer"') do (
set "VolIndex=%%a" set "VolIndex=%%a"
) )
rem 及时退出
if "%VolIndex%"=="" (
echo "Error: Cannot find installer partition." >&2
exit /b 1
)
rem 将 installer 分区设为 Y 盘 rem 将 installer 分区设为 Y 盘
(echo select vol %VolIndex% & echo assign letter=Y) | diskpart (echo select vol %VolIndex% & echo assign letter=Y) | diskpart
@ -93,6 +86,15 @@ for /f "tokens=3" %%a in (X:\disk.txt) do (
) )
del X:\disk.txt del X:\disk.txt
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
if "%is4kn%"=="1" ( if "%is4kn%"=="1" (
@ -105,6 +107,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,23 +115,31 @@ 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 命令
@ -140,6 +151,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 +196,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
@ -246,6 +276,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

@ -155,7 +155,9 @@
</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"
}
} }
} }
} }