From 139c342b7ea6df92e907f14cce7cb754e7340fcf Mon Sep 17 00:00:00 2001 From: bin456789 Date: Tue, 5 May 2026 22:55:00 +0800 Subject: [PATCH] =?UTF-8?q?windows:=20=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E9=9D=9E=20administrator=20=E8=B4=A6=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/run_reinstall.yml | 2 +- README.en.md | 6 ++- README.md | 6 ++- reinstall.sh | 71 ++++++++++++++++++++++++++++- trans.sh | 34 ++++++++++++-- windows.xml | 17 ++++++- 6 files changed, 124 insertions(+), 12 deletions(-) diff --git a/.github/workflows/run_reinstall.yml b/.github/workflows/run_reinstall.yml index 3fd5242..6d5067c 100644 --- a/.github/workflows/run_reinstall.yml +++ b/.github/workflows/run_reinstall.yml @@ -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 diff --git a/README.en.md b/README.en.md index 98d3a1b..89d982d 100644 --- a/README.en.md +++ b/README.en.md @@ -327,8 +327,9 @@ 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. - Automatically bypassing Windows 11 hardware requirements. @@ -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 diff --git a/README.md b/README.md index 3295807..0325708 100644 --- a/README.md +++ b/README.md @@ -327,8 +327,9 @@ bash reinstall.sh netboot.xyz > > 如果不小心运行了脚本,可以在重启前运行 `bash reinstall.sh reset` 取消重装 -- 用户名为 `administrator`,脚本会提示输入密码,不输入则使用随机密码 -- 如果远程登录失败,可以尝试使用用户名 `.\administrator` +- 脚本会提示输入用户名,不输入则使用 `administrator` +- 脚本会提示输入密码,不输入则使用随机密码 +- 如果远程登录失败,请尝试在用户名前添加 `.\`,例如 `.\administrator` - 静态机器会自动配置好 IP,可能首次开机几分钟后才生效 - 支持任意语言的 ISO - 自动绕过 Windows 11 硬件限制 @@ -446,6 +447,7 @@ bash reinstall.sh windows \ #### 可选参数 +- `--username USERNAME` 设置用户名(仅限 Windows) - `--password PASSWORD` 设置密码 - `--allow-ping` 设置 Windows 防火墙允许被 Ping - `--rdp-port PORT` 更改 RDP 端口 diff --git a/reinstall.sh b/reinstall.sh index 22a631e..eba8071 100644 --- a/reinstall.sh +++ b/reinstall.sh @@ -2342,6 +2342,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." @@ -3118,7 +3171,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" && @@ -4312,6 +4365,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: \ @@ -4446,6 +4500,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 @@ -4621,6 +4683,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 @@ -4900,7 +4967,7 @@ info 'info' echo "$distro $releasever" case "$distro" in -windows) username=administrator ;; +windows) username=${username:-administrator} ;; netboot.xyz) username= ;; dd | *) username=root ;; esac diff --git a/trans.sh b/trans.sh index b045db6..3d801cb 100644 --- a/trans.sh +++ b/trans.sh @@ -584,6 +584,10 @@ get_password_windows_administrator_base64() { get_config password-windows-administrator-base64 } +get_password_windows_user_base64() { + get_config password-windows-user-base64 +} + get_password_plaintext() { get_config password-plaintext } @@ -7175,20 +7179,44 @@ EOF } # 修改应答文件 + apk add xmlstarlet download $confhome/windows.xml /tmp/autounattend.xml locale=$(get_selected_image_prop 'Default Language') use_default_rdp_port=$(is_need_change_rdp_port && echo false || echo true) - password_base64=$(get_password_windows_administrator_base64) + # 7601.24214.180801-1700.win7sp1_ldr_escrow_CLIENT_ULTIMATE_x64FRE_en-us.iso Image Name 为空 # 将 xml Image Name 的值设为空可以正常安装 sed -i \ -e "s|%arch%|$arch|" \ -e "s|%image_name%|$image_name|" \ -e "s|%locale%|$locale|" \ - -e "s|%administrator_password%|$password_base64|" \ -e "s|%use_default_rdp_port%|$use_default_rdp_port|" \ /tmp/autounattend.xml + # 账号密码 + if [ -n "$username" ]; then + # 普通账号 + password_base64=$(get_password_windows_user_base64) + xmlstarlet ed -L -N x="urn:schemas-microsoft-com:unattend" \ + -d "//x:AdministratorPassword" \ + /tmp/autounattend.xml + sed -i \ + -e "s|%enable_administrator%|0|" \ + -e "s|%user_username%|$username|" \ + -e "s|%user_password%|$password_base64|" \ + /tmp/autounattend.xml + else + # Administrator + password_base64=$(get_password_windows_administrator_base64) + xmlstarlet ed -L -N x="urn:schemas-microsoft-com:unattend" \ + -d "//x:LocalAccounts" \ + /tmp/autounattend.xml + sed -i \ + -e "s|%enable_administrator%|1|" \ + -e "s|%administrator_password%|$password_base64|" \ + /tmp/autounattend.xml + fi + # 修改应答文件,分区配置 if is_efi; then sed -i "s|%installto_partitionid%|3|" /tmp/autounattend.xml @@ -7275,12 +7303,12 @@ EOF wim_windows_xml=$(get_path_in_correct_case /wim/windows.xml) wim_setup_exe=$(get_path_in_correct_case /wim/setup.exe) - apk add xmlstarlet xmlstarlet ed -d '//comment()' /tmp/autounattend.xml >$wim_autounattend_xml unix2dos $wim_autounattend_xml info "autounattend.xml" # 查看最终文件,并屏蔽密码 xmlstarlet ed -d '//*[name()="AdministratorPassword" or name()="Password"]' $wim_autounattend_xml | cat -n + apk del xmlstarlet # 避免无参数运行 setup.exe 时自动安装 diff --git a/windows.xml b/windows.xml index dc96f2f..66cd610 100644 --- a/windows.xml +++ b/windows.xml @@ -86,7 +86,7 @@ 4 powercfg /setactive SCHEME_MIN - + 5 @@ -94,7 +94,8 @@ - cmd /c "for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes && exit)" + + cmd /c "if "%enable_administrator%"=="1" for %a in (Administrator Administrador Administrateur Administratör Администратор Järjestelmänvalvoja Rendszergazda) do (net user %a /active:yes && exit)" @@ -152,6 +153,18 @@ %administrator_password% 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>