Sougen Blog

Windows 11 OOBE の sysprep スクリプトをフォークして自分のドメインに置いた

cloudflare-pagespowershellwindows

Windows 11 Home / Pro のセットアップ画面(OOBE)は Microsoft アカウントの作成またはログインを要求する。
ローカルアカウントで済ませたい時、zawa-lab のワンライナーが便利で、たまに使っている。

powershell -c "irm w1.zawa-lab.net/w|iex"

中身は、OOBE の中で unattend.xml を組み立てて sysprep /oobe /reboot を叩く PowerShell スクリプトだ。

ただ、w1.zawa-lab.net/w は毎回思い出せない。
それに、upstream が消えたり書き換わったりしても、こちらから気付く手段がない。
あと、自分はコンピューター名も入力段階で決めておきたい(元のスクリプトは Windows のデフォルトに任せる)。

そこで、CC BY-NC-SA は再配布と改変を認めているので、帰属表示を付けてフォークし、自分の管理下に置いた。

powershell -c "irm bypassnro.sougen.dev|iex"

fork の要件

これらは Cloudflare Pages で全部満たせる。

配信の仕組み

自分のリポジトリの src/header.htmlsrc/oobe-localaccount.ps1 を連結して dist/index.html に書き出す。

#!/usr/bin/env sh
set -eu

# 空ファイル押し込みなどを catch する簡易 sanity check
grep -q 'oobe-localaccount.ps1' src/oobe-localaccount.ps1

mkdir -p dist
cat src/header.html src/oobe-localaccount.ps1 > dist/index.html

Pages プロジェクトの build コマンドとして ./build.sh を指定してあるので、git push すると CF Pages が自動でビルド → デプロイまで走る。

なお、DNS は bypassnro.sougen.devbypassnro.pages.dev に CNAME して Proxy を有効にする。
証明書も配信も CF Pages 側が持つ。

独自機能: コンピューター名プロンプト

upstream との差分はスクリプト側の 1 点だけ。
User name と Password の入力に続いてコンピューター名を対話的に取得し、unattend.xmlspecialize パスに <ComputerName> を差し込む。

# --- computer name (optional) ---
while ($true) {
    $cn = (Read-Host 'Computer name (blank = Windows default)').Trim()
    if ($cn -eq '') { break }
    if ($cn.Length -gt 15) { ... continue }
    if ($cn -notmatch '^[A-Za-z0-9-]+$') { ... continue }
    if ($cn -match '^[0-9]+$') { ... continue }
    if ($cn -match '^-|-$') { ... continue }
    if ($cn -ieq $name) { ... continue }
    break
}

バリデーションは Windows のホスト名規約に沿った 5 点:15 文字以内、英数とハイフンのみ、全数字禁止、ハイフンで開始/終了禁止、ユーザー名と一致禁止。

空入力なら、unattend.xmlspecialize パス自体を出力しない(Windows のデフォルト命名に任せる)。
入力があった時のみ、以下のブロックを組み込む。

<settings pass="specialize">
  <component name="Microsoft-Windows-Shell-Setup" ...>
    <ComputerName>$cn</ComputerName>
  </component>
</settings>

初回セットアップの中で決めておくと、ドメイン参加もその後の作業も進めやすい。

HTML と PowerShell を両立させるハイブリッドコメント

案内用の src/header.html は、同じ URL を irm | iex で叩いてもブラウザで開いても機能するように書いてある。
先頭部分が、PowerShell のコメントとしても HTML のマークアップとしても成立する構造にしてある。
とある PowerShell スクリプトが採用している方式をそのまま真似した。

# This script is hosted at <b>https://bypassnro.sougen.dev</b><br>
# Fork of <a href="https://w1.zawa-lab.net/w">https://w1.zawa-lab.net/w</a> - adds an optional Computer name prompt.<br>
# Upstream article: <a href="https://w1.zawa-lab.net/p/20260728_oobe_bypass/">https://w1.zawa-lab.net/p/20260728_oobe_bypass/</a><br>
# License: CC BY-NC-SA 4.0 by zawa-lab (<a href="https://w1.zawa-lab.net/">https://w1.zawa-lab.net/</a>)<br>
# Usage:   powershell -c "irm bypassnro.sougen.dev|iex"<hr><pre>

要点は三つある。

各行が # で始まる
PowerShell では # から行末までがコメント扱いなので、HTML タグは実行時に完全に無視され、続くスクリプト本体だけが評価される。

各行末に <br> を置く
HTML では素の改行はスペース扱いなので、<br> を明示しないと 5 行のヘッダーが 1 行に潰れて表示される。
PowerShell 側では <br> はコメント内の文字列として無視される。

末尾の <hr><pre> を閉じない
閉じないまま HTML を終わらせると、その後に連結されるスクリプト本体がブラウザから見て <pre> 内のプレーンテキストとして表示される。
同じ 1 ファイルで「実行可能な PowerShell」と「読める Web ページ」を兼ねられる。

ライセンス

CC BY-NC-SA 4.0 は「同一条件で継承」なので、リポジトリの LICENSE には zawa-lab への帰属表示と、この配布物も同ライセンスであることを明記した。

なお、CC ライセンスが規制するのは複製・配布・翻案といった著作権上の行為なので、irm で取得して自分の PC で実行するだけの利用者にはそもそも影響しない。

まとめ

irm bypassnro.sougen.dev|iex で自分の fork(元は zawa-lab のスクリプト、コンピューター名プロンプトを追加)が走る。
配信は Cloudflare Pages のビルド枠だけで完結している。

良い Windows 11 ライフを。