# init-win

Windows 远程桌面机器初始化脚本，管理员账号登录后执行。

## 用法

```powershell
# 以管理员身份打开 PowerShell
cd C:\link\init-win.sh
.\admin-init.ps1 -RdpPort 33950
```

包含 10 个步骤：

1. **改管理员密码**：交互式输入（终端里手动敲两遍确认），不接受参数/配置文件传密码，避免明文落地。
2. **检查激活状态**：只查激活状态，不做激活本身，也不碰 Windows Defender（这台机器实际用第三方安全软件，Defender 防护开关会被接管/覆盖，脚本硬改容易失败，AV 允许名单是人工处理的手动步骤，不进这套自动化）。未激活直接退出，需要人工手动激活，激活成功后重新执行这个脚本；已激活就继续往下走。
3. **创建 `playz` 账号**：固定密码（来自 `config\settings.ps1`），加入 `Administrators` 组，禁止其自行修改密码。
4. **RDP 防火墙白名单**：只放行 `-RdpPort` 指定端口、白名单里的来源，关掉内置的"任何来源都放行"规则，其余入站流量默认拒绝。
5. **开启 WinRM**（供远程下发 PowerShell 命令用）：HTTPS 非标端口（`-WinRmPort`，默认 25986），10 年有效期自签名证书，同样只放行白名单来源。
6. **RDP 传输优化**：强制走纯 TCP（不走 UDP），打开终端服务层 + TCP 层两级 keepalive，减少长时间挂起后连接假死。
7. **RDP 会话时间限制**：已中断会话 15 分钟、空闲会话 30 分钟、活动会话 12 小时，超过限制结束会话（相当于注销，不是仅断开）。
8. **桌面视觉效果**：调整为"最佳性能" + 纯黑壁纸，应用到当前会话和新账号模板（让 `playz` 首次登录起就是这个配置）。
9. **系统时钟同步间隔 + 锁定时区**：把 Windows 时间服务（w32time）的同步间隔缩短到 3 分钟，装了磁盘还原保护（"影子系统"）的机器每次回滚都会带偏系统时钟，间隔太长会导致回滚后很久才重新对时，进而让 `login-totp`（本机 standalone TOTP 校验，30 秒容差）持续报验证码错误。同一步里顺带关掉"自动设置时区"（`tzautoupdate` 服务）并锁定为北京时间（`China Standard Time`，UTC+08:00）。
10. **安装 windows_exporter**：给 Prometheus 采集这台机器的系统指标（CPU/内存/磁盘/网络等），用 `vendor\` 里校验过 SHA256 的本地安装包静默安装，防火墙只放行 Prometheus 服务器一个来源。

`-RdpPort` 默认 `33950`，`-WinRmPort` 默认 `25986`。RDP/WinRM 白名单默认从 Galaxy 的运维通用白名单自动获取（`config\settings.ps1` 的 `$GalaxyApiBaseUrl`），`-WhitelistIPs`/`-WinRmWhitelistIPs` 是在这基础上追加的手动地址，不是必填；传了也是追加语义，多次运行会跟已登记的地址取并集，不会覆盖。传 `-Hostname`（跟 Galaxy 里登记这台机器的主机名一致）的话，RDP 白名单还会自动带上这台机器在 Galaxy 里的专属白名单，不用在命令行重复敲一遍同样的地址——WinRM 白名单不受 `-Hostname` 影响，只吃运维通用白名单：

```powershell
.\admin-init.ps1 -RdpPort 33950 -Hostname ajun-hk-01 -WhitelistIPs 1.2.3.4 -WinRmWhitelistIPs 9.9.9.9
```

可以用开关跳过某一步，方便断点续跑：

```powershell
.\admin-init.ps1 -SkipPasswordChange -SkipFirewall -SkipWinRM -SkipRdpTuning -SkipSessionTimeLimits -SkipDesktopPerfTweaks -SkipClockSync -SkipWindowsExporter
```

全部开关：`-SkipPasswordChange` `-SkipActivationCheck` `-SkipPlayzUser` `-SkipFirewall` `-SkipWinRM` `-SkipRdpTuning` `-SkipSessionTimeLimits` `-SkipDesktopPerfTweaks` `-SkipClockSync` `-SkipWindowsExporter`

## 执行前必须检查

- `config\settings.ps1` 里的 `$PlayzPassword` 已经写死成全部机器统一用的固定密码，不用再改；如果哪天要换，`admin-init.ps1` 仍然会在这个值等于旧占位符 `CHANGE_ME_BEFORE_RUNNING` 时拒绝执行步骤 3，这条保护还在，只是现在默认就不是占位值了
- `$AdminUsername` 默认是 `Administrator`，云主机如果改过名字要同步改这里
- `$GalaxyApiBaseUrl` 还是占位值的话，步骤 4/5 拿不到自动白名单（运维通用 + 专属都拿不到），退化成只用 `-WhitelistIPs`/`-WinRmWhitelistIPs` 手动传的地址（不会因此报错拒绝执行，只是少了自动白名单这一部分）
- 不传 `-Hostname` 的话，RDP 白名单只有运维通用白名单 + 手动传的地址，机器在 Galaxy 里的专属白名单不会自动带上

## 目录结构

```
init-win.sh\
  admin-init.ps1       入口脚本
  lib\Functions.ps1    共享函数（日志、幂等判断、SecureString 比较等）
  config\settings.ps1  配置（账号名、固定密码、windows_exporter 版本号+哈希）
  vendor\              windows_exporter 官方 MSI 本地副本，install 步骤唯一的安装包来源
```
