All checks were successful
release / build-and-release (push) Successful in 38s
Add Photos to the always-keep list (KeepPackages) like Calculator - the default image viewer should not be removed. It stays in the removal list but the keep-guard skips it and logs KEEP. Updates script header, CLAUDE.md DO-NOT, web spec table, descriptions.json and CHANGELOG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
219 lines
9.3 KiB
Markdown
219 lines
9.3 KiB
Markdown
# CLAUDE.md - Instructions for Claude Code
|
|
|
|
## Project context
|
|
|
|
MSP deployment tool for X9.cz - automated preparation of new Windows 10/11 computers.
|
|
Go GUI launcher (xetup.exe) embeds PowerShell scripts, runs them sequentially, handles
|
|
reboot cycles for Windows Update, and sends an email report when done.
|
|
|
|
**Key parameters:**
|
|
- Target OS: Windows 10 and Windows 11 (x64), including unsupported HW
|
|
- Execution: as Administrator on already-installed Windows (not WinPE/autounattend, not OOBE)
|
|
- Volume: ~20 machines per month, various clients
|
|
- Operator: MSP technician on-site at client
|
|
- Entry point: xetup.exe only (no CLI script entry point)
|
|
|
|
---
|
|
|
|
## Communication
|
|
|
|
- Communicate with the user in Czech
|
|
- Code, comments, log messages: English only (no diacritics rule still applies)
|
|
|
|
---
|
|
|
|
## Repo structure
|
|
|
|
```
|
|
xetup/
|
|
├── CLAUDE.md <- this file
|
|
├── SPEC.md <- technical specification
|
|
├── embed.go <- embeds scripts/ and assets/ into binary
|
|
├── cmd/xetup/
|
|
│ ├── main.go <- entry point: extract, load config, launch GUI
|
|
│ └── app.manifest <- Windows manifest (requireAdministrator)
|
|
├── internal/
|
|
│ ├── config/config.go <- Config struct, Load/Save, DefaultConfig
|
|
│ ├── gui/gui.go <- Walk GUI: form → run → summary (3 phases)
|
|
│ ├── runner/runner.go <- sequential PS script executor with log streaming
|
|
│ ├── state/state.go <- JSON state file for reboot-resume persistence
|
|
│ ├── prereboot/ <- autologon + X9-Resume scheduled task for reboot cycle
|
|
│ ├── preflight/ <- pre-run checks (admin, winget, network, disk)
|
|
│ └── report/report.go <- HTML email report via SMTP2Go
|
|
├── scripts/
|
|
│ ├── common.ps1 <- shared functions (Write-Log, Get-Feature, Load-Config)
|
|
│ ├── 00-admin-account.ps1 <- create hidden admin account (adminx9, no password)
|
|
│ ├── 01-bloatware.ps1 <- remove AppX, Capabilities, Features
|
|
│ ├── 02-software.ps1 <- parallel winget installs + Adobe PDF default + Atera
|
|
│ ├── 03-system-registry.ps1 <- HKLM tweaks, Edge policies, OneDrive, powercfg
|
|
│ ├── 04-default-profile.ps1 <- NTUSER.DAT + HKCU + personalization (merged)
|
|
│ ├── 07-backinfo.ps1 <- deploy BackInfo.exe + startup shortcut
|
|
│ ├── 08-activation.ps1 <- Windows activation (OA3 → config key → GVLK)
|
|
│ ├── 09-pc-identity.ps1 <- rename PC + C:\X9 folder (exit 9 on rename)
|
|
│ ├── 10-network.ps1 <- Private profile, ping, Network Discovery
|
|
│ ├── 11-dell-update.ps1 <- Dell Command | Update (auto-skip on non-Dell)
|
|
│ └── 12-windows-update.ps1 <- PSWindowsUpdate reboot cycle (exit 9)
|
|
├── config/
|
|
│ └── config.json <- default config template
|
|
├── assets/
|
|
│ ├── Backinfo/ <- BackInfo.exe + .ini
|
|
│ └── Logo/ <- X9-ikona.ico, X9-logo.jpeg
|
|
├── tests/
|
|
│ └── Test-Deployment.ps1 <- post-deployment verification
|
|
└── web/ <- xetup.x9.cz static site
|
|
```
|
|
|
|
---
|
|
|
|
## Execution flow
|
|
|
|
```
|
|
xetup.exe start
|
|
→ extract scripts/ and assets/ to temp dir
|
|
→ state file exists? → resume mode (skip form, run pending steps)
|
|
→ normal mode:
|
|
1. Pre-flight checks (admin, winget, network, disk) shown in GUI
|
|
2. Config form (PC name, key, profile, step checkboxes)
|
|
3. Write runtime config JSON (reflects GUI selections)
|
|
4. Run steps sequentially via powershell.exe -File -ConfigPath -LogFile
|
|
5. Step exits 9? → save state, setup autologon + X9-Resume task, reboot
|
|
6. After reboot → xetup resumes, runs remaining steps
|
|
7. All done → cleanup autologon, send email report, show summary
|
|
```
|
|
|
|
## Step execution order
|
|
|
|
```
|
|
00 Admin account (adminx9)
|
|
08 Windows activation
|
|
01 Bloatware removal
|
|
02 Software (parallel winget + Atera + PDF default)
|
|
03 System Registry (HKLM + Edge policies)
|
|
04 Default Profile + Personalization (single hive load)
|
|
07 BackInfo
|
|
10 Network discovery
|
|
11 Dell Command | Update
|
|
09 PC identity (rename triggers reboot via exit 9)
|
|
12 Windows Update (reboot cycle via exit 9)
|
|
```
|
|
|
|
---
|
|
|
|
## Conventions and rules
|
|
|
|
### PowerShell
|
|
- All scripts use `common.ps1` (dot-sourced): Write-Log, Get-Feature, Load-Config
|
|
- Scripts receive `-ConfigPath` (path to JSON) and `-LogFile` params
|
|
- Scripts parse config themselves via `Load-Config $ConfigPath`
|
|
- `$ErrorActionPreference = "Continue"` - scripts survive partial failures
|
|
- Exit code 9 = "reboot required" - runner saves state and triggers restart
|
|
- Log to `C:\Windows\Setup\Scripts\Deploy.log`
|
|
- NO diacritics anywhere (encoding issues across systems)
|
|
- NO emoticons
|
|
|
|
### Go / GUI
|
|
- Walk-based GUI (Windows only, CGO required)
|
|
- Cross-compile: `CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc GOOS=windows GOARCH=amd64`
|
|
- Three phases: config form → live log → summary with reboot countdown
|
|
- Features system: steps can have sub-features (checkboxes in GUI), controlled via config.features
|
|
|
|
### Config
|
|
- `config.json` is the template, `config-runtime.json` is written to temp at runtime
|
|
- GUI regenerates runtime config before starting the run
|
|
- `DefaultConfig()` in config.go provides sensible defaults when config.json is absent
|
|
- Features default to `true` when missing from config
|
|
|
|
### Testing
|
|
- Test VM: Windows 10/11 x64 on VMware ESXi
|
|
- Before each test: take snapshot, after test: revert
|
|
- Dev environment: x64 VM only (not ARM)
|
|
|
|
---
|
|
|
|
## Key implementation details
|
|
|
|
### Admin account (adminx9)
|
|
- No password (empty), hidden from login screen, Administrators group
|
|
- FullName = "X9.cz s.r.o." (via ADSI)
|
|
- Also used by prereboot for autologon during reboot cycles
|
|
|
|
### Edge policies
|
|
- Mandatory (`Policies\Microsoft\Edge`): HideFirstRunExperience, DefaultBrowserSettingEnabled, DiagnosticData, FeedbackSurveysEnabled
|
|
- Recommended (`Policies\Microsoft\Edge\Recommended`): everything else (user can override)
|
|
|
|
### PDF default
|
|
- Adobe Reader set via HKCR\.pdf after install
|
|
- UCPD driver stopped during association write, restarted after
|
|
|
|
### Reboot-resume cycle
|
|
- `prereboot_windows.go`: copies xetup.exe to stable path, sets autologon for adminx9, registers X9-Resume scheduled task
|
|
- `state.go`: persists pending steps + accumulated results across reboots
|
|
- Steps 09 (pcIdentity on rename) and 12 (windowsUpdate) can trigger exit 9
|
|
- Cleanup: disables autologon, removes X9-Resume task
|
|
|
|
### Email report
|
|
- Sent via SMTP2Go (mail-eu.smtp2go.com:2525) at end of deployment
|
|
- From: xetup@x9.cz, To: net@x9.cz
|
|
- Subject: "xetup report HOSTNAME"
|
|
- HTML body with per-step status table
|
|
|
|
### Parallel winget
|
|
- 02-software.ps1 launches all winget installs as background jobs (Start-Job)
|
|
- Jobs run simultaneously, results collected after all complete
|
|
- Every install passes `--source winget` (msstore source fails on fresh Win11 ISOs: 0x8a15005e)
|
|
|
|
### Atera agent
|
|
- Installed under NT AUTHORITY\SYSTEM via a one-shot scheduled task (msiexec /qn) - under SYSTEM
|
|
there is no interactive MFA prompt. Verified via the AteraAgent service (path check fallback).
|
|
|
|
### Keyboard + accent (step 04)
|
|
- Keyboard: CZ primary + US secondary (Set-WinUserLanguageList + Preload in Default hive and HKU\.DEFAULT)
|
|
- Accent #223B47 needs AccentColor AND AccentPalette (REG_BINARY) or Win11 drops it on Start/taskbar
|
|
- Theme written to Default hive + current HKCU + HKU\.DEFAULT so all profiles match
|
|
- File Explorer pinned via AUMID (Microsoft.Windows.Explorer), not a custom .lnk (avoids 2nd Explorer)
|
|
- BackInfo.ini BackgroundColor is 0xRRGGBB decimal (RGB, not COLORREF): #223B47 = 2243399
|
|
|
|
### Code signing
|
|
- CI signs xetup.exe via Azure Trusted Signing (cert "X9.cz s.r.o.") + jsign + RFC3161 timestamp
|
|
- Certs are short-lived (~3 days); the timestamp keeps signatures valid past expiry
|
|
- Only AZURE_CLIENT_SECRET is a Forgejo Actions secret; the SP is shared across X9 projects - do NOT rotate
|
|
- jsign auth needs the Trusted Signing token; runner-config mounts the docker socket for the deploy.json step
|
|
|
|
---
|
|
|
|
## Workflow
|
|
|
|
- Do NOT start coding until explicitly approved - discuss the plan first
|
|
- Propose changes, wait for confirmation, then implement
|
|
|
|
### Pushing to Forgejo
|
|
|
|
```bash
|
|
TOKEN=$(sudo docker exec -u git xetup-forgejo forgejo admin user generate-access-token \
|
|
--username x9 --token-name "push-$(date +%s)" --raw --scopes "write:repository")
|
|
git push "http://x9:${TOKEN}@localhost:3100/x9/xetup.git" main
|
|
```
|
|
|
|
---
|
|
|
|
## DO NOT
|
|
|
|
- Do not use `$ErrorActionPreference = "Stop"` - scripts must survive partial failure
|
|
- Do not remove Calculator (Microsoft.WindowsCalculator)
|
|
- Do not remove Photos (Microsoft.Windows.Photos)
|
|
- Do not use ARM VM for testing
|
|
- Do not write scripts depending on specific username
|
|
- Do not use hardcoded paths that do not exist on clean Windows
|
|
- NO diacritics in any file
|
|
- NO emoticons
|
|
- Do not remove OneDrive policy-block-free (M365 must be able to reinstall it)
|
|
- Do not remove RDP/RDS or Microsoft-RemoteDesktopConnection
|
|
- Do not create Deploy-Windows.ps1 or other CLI entry points (xetup.exe is sole entry point)
|
|
|
|
---
|
|
|
|
## Open questions
|
|
|
|
| # | Question | Status |
|
|
|---|---|---|
|
|
| 1 | Complete SW list for winget | TODO - list may be incomplete |
|