windows: dd / iso 安装后添加静态网络配置
This commit is contained in:
parent
1acdaaee2b
commit
e5efd0adc9
@ -17,7 +17,7 @@ if not !errorlevel! == 0 (
|
|||||||
)
|
)
|
||||||
|
|
||||||
:: pkgs 改动了才重新运行 Cygwin 安装程序
|
:: pkgs 改动了才重新运行 Cygwin 安装程序
|
||||||
set pkgs="curl,cpio,p7zip,bind-utils"
|
set pkgs="curl,cpio,p7zip,bind-utils,ipcalc"
|
||||||
set tags=%tmp%\cygwin-installed-!pkgs!
|
set tags=%tmp%\cygwin-installed-!pkgs!
|
||||||
if not exist !tags! (
|
if not exist !tags! (
|
||||||
:: 检查是否国内
|
:: 检查是否国内
|
||||||
@ -75,7 +75,7 @@ exit /b !errorlevel!
|
|||||||
|
|
||||||
|
|
||||||
:download
|
:download
|
||||||
:: coreutil 会被 windows Defender 报毒
|
:: certutil 会被 windows Defender 报毒
|
||||||
:: certutil -urlcache -f -split %~1 %~2
|
:: certutil -urlcache -f -split %~1 %~2
|
||||||
bitsadmin /transfer "%~3" /priority foreground %~1 %~2
|
bitsadmin /transfer "%~3" /priority foreground %~1 %~2
|
||||||
exit /b !errorlevel!
|
exit /b !errorlevel!
|
||||||
|
259
trans.sh
259
trans.sh
@ -330,19 +330,54 @@ is_dhcpv6() {
|
|||||||
[ "$dhcpv6" = 1 ]
|
[ "$dhcpv6" = 1 ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to_upper() {
|
||||||
|
tr '[:lower:]' '[:upper:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
to_lower() {
|
||||||
|
tr '[:upper:]' '[:lower:]'
|
||||||
|
}
|
||||||
|
|
||||||
|
unix2dos() {
|
||||||
|
target=$1
|
||||||
|
|
||||||
|
# 先原地unix2dos,出错再用复制,可最大限度保留文件权限
|
||||||
|
if ! command unix2dos $target 2>/tmp/error.log; then
|
||||||
|
# 出错后删除 unix2dos 创建的临时文件
|
||||||
|
rm "$(awk -F: '{print $2}' /tmp/error.log | xargs)"
|
||||||
|
tmp=$(mktemp)
|
||||||
|
cp $target $tmp
|
||||||
|
command unix2dos $tmp
|
||||||
|
cp $tmp $target
|
||||||
|
rm $tmp
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
insert_into_file() {
|
insert_into_file() {
|
||||||
file=$1
|
file=$1
|
||||||
location=$2
|
location=$2
|
||||||
regex_to_find=$3
|
regex_to_find=$3
|
||||||
|
|
||||||
line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1)
|
if [ "$location" = HEAD ]; then
|
||||||
if [ "$location" = before ]; then
|
in=$(mktemp)
|
||||||
line_num=$((line_num - 1))
|
cat /dev/stdin >$in
|
||||||
elif ! [ "$location" = after ]; then
|
echo -e "0r $in \n w \n q" | ed $file >/dev/null
|
||||||
return 1
|
else
|
||||||
fi
|
line_num=$(grep -E -n "$regex_to_find" "$file" | cut -d: -f1)
|
||||||
|
|
||||||
sed -i "${line_num}r /dev/stdin" "$file"
|
found_count=$(echo "$line_num" | wc -l)
|
||||||
|
if [ ! "$found_count" -eq 1 ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$location" in
|
||||||
|
before) line_num=$((line_num - 1)) ;;
|
||||||
|
after) ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
sed -i "${line_num}r /dev/stdin" "$file"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_alpine() {
|
install_alpine() {
|
||||||
@ -812,35 +847,109 @@ EOF
|
|||||||
cat -n $ci_file
|
cat -n $ci_file
|
||||||
}
|
}
|
||||||
|
|
||||||
modify_dd_os() {
|
modify_windows() {
|
||||||
|
# https://learn.microsoft.com/zh-cn/windows-hardware/manufacture/desktop/windows-setup-states
|
||||||
|
# https://learn.microsoft.com/zh-cn/troubleshoot/azure/virtual-machines/reset-local-password-without-agent
|
||||||
|
# https://learn.microsoft.com/zh-cn/windows-hardware/manufacture/desktop/add-a-custom-script-to-windows-setup
|
||||||
|
|
||||||
|
# 判断用 SetupComplete 还是组策略
|
||||||
|
state_ini=/os/Windows/Setup/State/State.ini
|
||||||
|
cat $state_ini
|
||||||
|
if grep -q IMAGE_STATE_COMPLETE $state_ini; then
|
||||||
|
use_gpo=true
|
||||||
|
else
|
||||||
|
use_gpo=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 下载共同的子脚本
|
||||||
|
# 可能 unattend.xml 已经设置了ExtendOSPartition,不过运行resize没副作用
|
||||||
|
bats="windows-resize.bat windows-set-netconf.bat"
|
||||||
|
download $confhome/windows-resize.bat /os/windows-resize.bat
|
||||||
|
create_win_set_netconf_script /os/windows-set-netconf.bat
|
||||||
|
|
||||||
|
if $use_gpo; then
|
||||||
|
# 使用组策略
|
||||||
|
gpt_ini=/os/Windows/System32/GroupPolicy/gpt.ini
|
||||||
|
scripts_ini=/os/Windows/System32/GroupPolicy/Machine/Scripts/scripts.ini
|
||||||
|
mkdir -p "$(dirname $scripts_ini)"
|
||||||
|
|
||||||
|
# 备份 ini
|
||||||
|
for file in $gpt_ini $scripts_ini; do
|
||||||
|
if [ -f $file ]; then
|
||||||
|
cp $file $file.orig
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# gpt.ini
|
||||||
|
cat >$gpt_ini <<EOF
|
||||||
|
[General]
|
||||||
|
gPCFunctionalityVersion=2
|
||||||
|
gPCMachineExtensionNames=[{42B5FAAE-6536-11D2-AE5A-0000F87571E3}{40B6664F-4972-11D1-A7CA-0000F87571E3}]
|
||||||
|
Version=1
|
||||||
|
EOF
|
||||||
|
unix2dos $gpt_ini
|
||||||
|
|
||||||
|
# scripts.ini
|
||||||
|
if ! [ -e $scripts_ini ]; then
|
||||||
|
touch $scripts_ini
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! grep -F '[Startup]' $scripts_ini; then
|
||||||
|
echo '[Startup]' >>$scripts_ini
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 注意没用 pipefail 的话,错误码取自最后一个管道
|
||||||
|
if num=$(grep -Eo '^[0-9]+' $scripts_ini | sort -n | tail -1 | grep .); then
|
||||||
|
num=$((num + 1))
|
||||||
|
else
|
||||||
|
num=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
bats="$bats windows-del-gpo.bat"
|
||||||
|
for bat in $bats; do
|
||||||
|
echo "${num}CmdLine=%SystemDrive%\\$bat" >>$scripts_ini
|
||||||
|
echo "${num}Parameters=" >>$scripts_ini
|
||||||
|
num=$((num + 1))
|
||||||
|
done
|
||||||
|
cat $scripts_ini
|
||||||
|
unix2dos $scripts_ini
|
||||||
|
|
||||||
|
# windows-del-gpo.bat
|
||||||
|
download $confhome/windows-del-gpo.bat /os/windows-del-gpo.bat
|
||||||
|
else
|
||||||
|
# 使用 SetupComplete
|
||||||
|
setup_complete=/os/Windows/Setup/Scripts/SetupComplete.cmd
|
||||||
|
mkdir -p "$(dirname $setup_complete)"
|
||||||
|
|
||||||
|
# 添加到 C:\Setup\Scripts\SetupComplete.cmd 最前面
|
||||||
|
# call 防止子 bat 删除自身后中断主脚本
|
||||||
|
my_setup_complete=$(mktemp)
|
||||||
|
for bat in $bats; do
|
||||||
|
echo "if exist %SystemDrive%\\$bat (call %SystemDrive%\\$bat)" >>$my_setup_complete
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -f $setup_complete ]; then
|
||||||
|
# 直接插入而不是覆盖,可以保留权限,虽然没什么影响
|
||||||
|
insert_into_file $setup_complete HEAD <$my_setup_complete
|
||||||
|
else
|
||||||
|
cp $my_setup_complete $setup_complete
|
||||||
|
fi
|
||||||
|
|
||||||
|
unix2dos $setup_complete
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
modify_linux() {
|
||||||
|
os_dir=$1
|
||||||
|
|
||||||
find_and_mount() {
|
find_and_mount() {
|
||||||
mount_point=$1
|
mount_point=$1
|
||||||
|
|
||||||
mount_dev=$(awk "\$2==\"$mount_point\" {print \$1}" $os_dir/etc/fstab)
|
mount_dev=$(awk "\$2==\"$mount_point\" {print \$1}" $os_dir/etc/fstab)
|
||||||
if [ -n "$mount_dev" ]; then
|
if [ -n "$mount_dev" ]; then
|
||||||
mount $mount_dev $os_dir$mount_point
|
mount $mount_dev $os_dir$mount_point
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
apk add lsblk
|
|
||||||
mkdir -p /os
|
|
||||||
# 按分区容量大到小,依次寻找系统分区
|
|
||||||
for part in $(lsblk /dev/$xda --sort SIZE -no NAME | sed '$d' | tac); do
|
|
||||||
# btrfs挂载的是默认子卷,如果没有默认子卷,挂载的是根目录
|
|
||||||
# fedora 云镜像没有默认子卷,且系统在root子卷中
|
|
||||||
if mount /dev/$part /os; then
|
|
||||||
if etc_dir=$({ ls -d /os/etc || ls -d /os/*/etc; } 2>/dev/null); then
|
|
||||||
os_dir=$(dirname $etc_dir)
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
umount /os
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ -z "$os_dir" ]; then
|
|
||||||
error_and_exit "can't find os partition"
|
|
||||||
fi
|
|
||||||
|
|
||||||
download_cloud_init_config $os_dir
|
download_cloud_init_config $os_dir
|
||||||
|
|
||||||
# 为红帽系禁用 selinux kdump
|
# 为红帽系禁用 selinux kdump
|
||||||
@ -894,12 +1003,39 @@ EOF
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_cloud_image_by_dd() {
|
modify_os_on_disk() {
|
||||||
apk add util-linux udev hdparm curl
|
apk add util-linux udev hdparm lsblk
|
||||||
rc-service udev start
|
rc-service udev start
|
||||||
install_dd
|
|
||||||
update_part /dev/$xda
|
update_part /dev/$xda
|
||||||
modify_dd_os
|
|
||||||
|
mkdir -p /os
|
||||||
|
# 按分区容量大到小,依次寻找系统分区
|
||||||
|
for part in $(lsblk /dev/$xda --sort SIZE -no NAME | sed '$d' | tac); do
|
||||||
|
# btrfs挂载的是默认子卷,如果没有默认子卷,挂载的是根目录
|
||||||
|
# fedora 云镜像没有默认子卷,且系统在root子卷中
|
||||||
|
if mount -o ro /dev/$part /os; then
|
||||||
|
if etc_dir=$({ ls -d /os/etc/ || ls -d /os/*/etc/; } 2>/dev/null); then
|
||||||
|
os_dir=$(dirname $etc_dir)
|
||||||
|
# 重新挂载为读写
|
||||||
|
mount -o remount,rw /os
|
||||||
|
modify_linux $os_dir
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# find 有时会报 I/O error
|
||||||
|
if ls -d /os/*/ | grep -i '/windows/' 2>/dev/null; then
|
||||||
|
# 重新挂载为读写、忽略大小写
|
||||||
|
umount /os
|
||||||
|
apk add ntfs-3g
|
||||||
|
mount.lowntfs-3g /dev/$part /os -o ignore_case
|
||||||
|
modify_windows /os
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
umount_os
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
error_and_exit "Can't find os partition."
|
||||||
}
|
}
|
||||||
|
|
||||||
create_swap() {
|
create_swap() {
|
||||||
@ -1247,6 +1383,62 @@ mount_part() {
|
|||||||
mount $mount_args /dev/disk/by-label/installer /os/installer
|
mount $mount_args /dev/disk/by-label/installer /os/installer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_dns_list_for_win() {
|
||||||
|
case "$1" in
|
||||||
|
4) sign='\.' ;;
|
||||||
|
6) sign=':' ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if dns_list=$(grep '^nameserver' /etc/resolv.conf | awk '{print $2}' | grep "$sign"); then
|
||||||
|
i=0
|
||||||
|
for dns in $dns_list; do
|
||||||
|
i=$((i + 1))
|
||||||
|
echo "set ipv${1}_dns$i=$dns"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
create_win_set_netconf_script() {
|
||||||
|
target=$1
|
||||||
|
|
||||||
|
if is_staticv4 || is_staticv6; then
|
||||||
|
get_netconf_to mac_addr
|
||||||
|
echo "set mac_addr=$mac_addr" >$target
|
||||||
|
|
||||||
|
# 生成静态 ipv4 配置
|
||||||
|
if is_staticv4; then
|
||||||
|
get_netconf_to ipv4_addr
|
||||||
|
get_netconf_to ipv4_gateway
|
||||||
|
ipv4_dns_list="$(get_dns_list_for_win 4)"
|
||||||
|
cat <<EOF >>$target
|
||||||
|
set ipv4_addr=$ipv4_addr
|
||||||
|
set ipv4_gateway=$ipv4_gateway
|
||||||
|
$ipv4_dns_list
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 生成静态 ipv6 配置
|
||||||
|
if is_staticv6; then
|
||||||
|
get_netconf_to ipv6_addr
|
||||||
|
get_netconf_to ipv6_gateway
|
||||||
|
ipv6_dns_list="$(get_dns_list_for_win 6)"
|
||||||
|
cat <<EOF >>$target
|
||||||
|
set ipv6_addr=$ipv6_addr
|
||||||
|
set ipv6_gateway=$ipv6_gateway
|
||||||
|
$ipv6_dns_list
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat -n $target
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 脚本还有关闭ipv6隐私id的功能,所以不能省略
|
||||||
|
# 合并脚本
|
||||||
|
wget $confhome/windows-set-netconf.bat -O- >>$target
|
||||||
|
unix2dos $target
|
||||||
|
}
|
||||||
|
|
||||||
install_windows() {
|
install_windows() {
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
download $iso /os/windows.iso
|
download $iso /os/windows.iso
|
||||||
@ -1542,7 +1734,8 @@ EOF
|
|||||||
# TODO: 由于esd文件无法修改,要将resize.bat放到boot.wim
|
# TODO: 由于esd文件无法修改,要将resize.bat放到boot.wim
|
||||||
if [[ "$install_wim" = "*.wim" ]]; then
|
if [[ "$install_wim" = "*.wim" ]]; then
|
||||||
wimmountrw $install_wim "$image_name" /wim/
|
wimmountrw $install_wim "$image_name" /wim/
|
||||||
download $confhome/resize.bat /wim/resize.bat
|
download $confhome/windows-resize.bat /wim/windows-resize.bat
|
||||||
|
create_win_set_netconf_script /wim/windows-set-netconf.bat
|
||||||
wimunmount --commit /wim/
|
wimunmount --commit /wim/
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
16
windows-del-gpo.bat
Normal file
16
windows-del-gpo.bat
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
@echo off
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
set "files[1]=%windir%\System32\GroupPolicy\gpt.ini"
|
||||||
|
set "files[2]=%windir%\System32\GroupPolicy\Machine\Scripts\scripts.ini"
|
||||||
|
|
||||||
|
for %%i in (1 2) do (
|
||||||
|
set "ini=!files[%%i]!"
|
||||||
|
if exist "!ini!.orig" (
|
||||||
|
move /y "!ini!.orig" "!ini!"
|
||||||
|
) else (
|
||||||
|
del "!ini!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
del "%~f0"
|
@ -1,3 +1,5 @@
|
|||||||
|
@echo off
|
||||||
set C=%SystemDrive:~0,1%
|
set C=%SystemDrive:~0,1%
|
||||||
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr /i "installer"') do (echo select disk 0 & echo select vol %%a & echo delete partition) | diskpart
|
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<installer\>"') do (echo select vol %%a & echo delete partition) | diskpart
|
||||||
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<%C%\>"') do (echo select disk 0 & echo select vol %%a & echo extend) | diskpart
|
for /f "tokens=2" %%a in ('echo list vol ^| diskpart ^| findstr "\<%C%\>"') do (echo select vol %%a & echo extend) | diskpart
|
||||||
|
del "%~f0"
|
||||||
|
45
windows-set-netconf.bat
Normal file
45
windows-set-netconf.bat
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
rem set mac_addr=11:22:33:aa:bb:cc
|
||||||
|
|
||||||
|
rem set ipv4_addr=192.168.1.2/24
|
||||||
|
rem set ipv4_gateway=192.168.1.1
|
||||||
|
rem set ipv4_dns1=192.168.1.1
|
||||||
|
rem set ipv4_dns2=192.168.1.2
|
||||||
|
|
||||||
|
rem set ipv6_addr=2222::2/64
|
||||||
|
rem set ipv6_gateway=2222::1
|
||||||
|
rem set ipv6_dns1=::1
|
||||||
|
rem set ipv6_dns2=::2
|
||||||
|
|
||||||
|
@echo off
|
||||||
|
setlocal EnableDelayedExpansion
|
||||||
|
|
||||||
|
:: 关闭随机地址,防止ipv6地址和后台面板不一致
|
||||||
|
netsh interface ipv6 set global randomizeidentifiers=disabled
|
||||||
|
|
||||||
|
if not defined mac_addr exit /b
|
||||||
|
for /f %%a in ('wmic nic where "MACAddress='%mac_addr%'" get InterfaceIndex ^| findstr [0-9]') do set id=%%a
|
||||||
|
if not defined id exit /b
|
||||||
|
|
||||||
|
if defined ipv4_addr if defined ipv4_gateway (
|
||||||
|
:: gwmetric 默认值为 1,自动跃点需设为 0
|
||||||
|
netsh interface ipv4 set address %id% static %ipv4_addr% gateway=%ipv4_gateway% gwmetric=0
|
||||||
|
|
||||||
|
for %%i in (1, 2) do (
|
||||||
|
if defined ipv4_dns%%i (
|
||||||
|
netsh interface ipv4 add dnsservers %id% !ipv4_dns%%i! %%i no
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if defined ipv6_addr if defined ipv6_gateway (
|
||||||
|
netsh interface ipv6 set address %id% %ipv6_addr%
|
||||||
|
netsh interface ipv6 add route prefix=::/0 %id% !ipv6_gateway!
|
||||||
|
|
||||||
|
for %%i in (1, 2) do (
|
||||||
|
if defined ipv6_dns%%i (
|
||||||
|
netsh interface ipv6 add dnsservers %id% !ipv6_dns%%i! %%i no
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
del "%~f0"
|
@ -98,18 +98,13 @@
|
|||||||
<Order>4</Order>
|
<Order>4</Order>
|
||||||
<Path>net user Administrator /active:yes</Path>
|
<Path>net user Administrator /active:yes</Path>
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
<!-- workaround esd 里面没有这个文件,先touch -->
|
|
||||||
<RunSynchronousCommand wcm:action="add">
|
<RunSynchronousCommand wcm:action="add">
|
||||||
<Order>5</Order>
|
<Order>5</Order>
|
||||||
<Path>cmd /c type nul >>C:\resize.bat</Path>
|
<Path>cmd /c "if exist %SystemDrive%\windows-resize.bat (call %SystemDrive%\windows-resize.bat)"</Path>
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
<RunSynchronousCommand wcm:action="add">
|
<RunSynchronousCommand wcm:action="add">
|
||||||
<Order>6</Order>
|
<Order>6</Order>
|
||||||
<Path>C:\resize.bat</Path>
|
<Path>cmd /c "if exist %SystemDrive%\windows-set-netconf.bat (call %SystemDrive%\windows-set-netconf.bat)"</Path>
|
||||||
</RunSynchronousCommand>
|
|
||||||
<RunSynchronousCommand wcm:action="add">
|
|
||||||
<Order>7</Order>
|
|
||||||
<Path>cmd /c "del C:\resize.bat"</Path>
|
|
||||||
</RunSynchronousCommand>
|
</RunSynchronousCommand>
|
||||||
</RunSynchronous>
|
</RunSynchronous>
|
||||||
</component>
|
</component>
|
||||||
|
Loading…
Reference in New Issue
Block a user